本文主要是介绍libvncclient编写多线程qt的VNC客户端,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
概述
- 使用qt和libvncclient编写vnc的客户端程序,多线程读写,拒绝卡顿。
- qt环境:5.15.3
- libvncclient:0.9.14
- 下载地址:https://github.com/LibVNC/libvncserver/releases
编译libvncclient
- 打开CMakeList文件,找到编译开关,注释掉不需要的编译项目:
# all the build configuration switches
option(LIBVNCSERVER_INSTALL "Generate installation target" ON)
option(BUILD_SHARED_LIBS "Build shared libraries" ${UNIX})
option(WITH_ZLIB "Search for the zlib compression library to support additional encodings" ON)
option(WITH_LZO "Search for the LZO compression library to omit internal miniLZO implementation" ON)
option(WITH_JPEG "Search for the libjpeg compression library to support additional encodings" ON)
option(WITH_PNG "Search for the PNG compression library to support additional encodings" ON)
option(WITH_SDL "Search for the Simple Direct Media Layer library to build an example SDL vnc client" ON)
option(WITH_GTK "Search for the GTK library to build an example GTK vnc client" ON)
option(WITH_LIBSSHTUNNEL "Search for libsshtunnel to build an example ssh-tunneled client" ON)
option(WITH_THREADS "Search for a threading library to build with multithreading support" ON)
option(PREFER_WIN32THREADS "When searching for a threading library, prefer win32 threads if they are found" ON)
option(WITH_GNUTLS "Search for the GnuTLS secure communications library to support TLS" OFF)
option(WITH_OPENSSL "Search for the OpenSSL cryptography library to support TLS and use as crypto backend" ON)
option(WITH_SYSTEMD "Search for libsystemd to build with systemd socket activation support" ON)
option(WITH_GCRYPT "Search for Libgcrypt to use as crypto backend" ON)
option(WITH_FFMPEG "Search for FFMPEG to build an example VNC to MPEG encoder" ON)
option(WITH_TIGHTVNC_FILETRANSFER "Enable filetransfer if there is pthreads support" ON)
option(WITH_24BPP "Allow 24 bpp" ON)
option(WITH_IPv6 "Enable IPv6 Support" ON)
option(WITH_WEBSOCKETS "Build with websockets support" ON)
option(WITH_SASL "Build with SASL support" ON)
option(WITH_XCB "Build with XCB support" ON)
option(WITH_EXAMPLES "Build examples" OFF)
option(WITH_TESTS "Build tests" OFF)
option(WITH_QT "Build the Qt client example" OFF)
- 也可以自己手动去掉不需要的库依赖,我这里没有把server的库依赖去干净。
- 然后取出项目中的libvncclient.so和头文件中的client目录到自己的项目中。
- 将build目录中的include中的rfbconfig.h拷贝到头文件目录
项目思路
- 主要思路如下:
- 创建一个主窗口QWidget用于画面渲染,创建一个接收线程和一个发送线程。
- 接收线程负责读取vnc服务器发送的数据并解码装换成QImage,通过信号发送QImage,通知主线程刷新页面。
- 发送线程用于发送主窗口的鼠标移动,点击等事件,用于实时更新操作。
项目编写
- VncWideget : 主要的渲染窗口
#ifndef VNCVIEWWIDGET_H
#define VNCVIEWWIDGET_H#include <QWidget>
#include <QThread>#include "rfb/rfbclient.h"
#include "rfb/rfbconfig.h"#include "vnc_client/vncrecvthread.h"
#include "vnc_client/vncsendworker.h"class VncViewWidget : public QWidget
{Q_OBJECT
public:explicit VncViewWidget(QString ip, quint32 port, QWidget *parent = nullptr);~VncViewWidget();void start();void stop();inline bool isStarted(){return _startFlag;}void updateImage(const QImage& image);void paintEvent(QPaintEvent *event) override;void mouseMoveEvent(QMouseEvent* event) override;void mousePressEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;void closeEvent(QCloseEvent* event) override;private:QImage _image;rfbClient *_cl;QString _ip;quint32 _port;bool _startFlag = false;QThread* _vncSendThread;VNCSendWorker* _vncSendWorker;VNCRecvThread* _vncRecvThread;signals:void sendMouseState(rfbClient* cl, int x, int y, int button);void fullWindowCloseSignal();public slots:
};#endif // VNCVIEWWIDGET_H
- VNCSendWorker:数据发送工作线程
#ifndef VNCSENDWORKER_H
#define VNCSENDWORKER_H#include <QObject>#include "rfb/rfbclient.h"class VNCSendWorker : public QObject
{Q_OBJECT
public:explicit VNCSendWorker( QObject *parent = nullptr);signals:public slots:void sendMouseUpdateMsg(rfbClient* cl, int x, int y, int button);};#endif // VNCSENDWORKER_H
VNCRecvThread :接收线程
#ifndef VNCRECVTHREAD_H
#define VNCRECVTHREAD_H#include <QThread>#include <QImage>#include "rfb/rfbclient.h"class VNCRecvThread : public QThread
{Q_OBJECT
public:VNCRecvThread(QObject* parent = nullptr);inline void startRun(rfbClient* cl){if(_runFlag)return;_cl = cl;_cl->FinishedFrameBufferUpdate = frameBufferUpdated;rfbClientSetClientData(_cl, nullptr, this);_runFlag = true;this->start();}inline void stopRun(){if(!_runFlag)return;_runFlag = false;if(_cl)rfbClientSetClientData(_cl, nullptr, nullptr);if(_cl)_cl->FinishedFrameBufferUpdate = nullptr;_cl = nullptr;}static void frameBufferUpdated(rfbClient* cl);protected:void run() override;private:bool _runFlag = false;rfbClient* _cl;signals:void updateImageSignal(QImage);
};#endif // VNCRECVTHREAD_H
项目完整代码
gitee:https://gitee.com/li-gouhi2333/vncclient/tree/master/
这篇关于libvncclient编写多线程qt的VNC客户端的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!