17zwd一起做网站广州新塘,wordpress 付费字段,华为云wordpress淘宝,万州网站建设果园路文章目录 CMakeQT大漠插件的桌面应用开发#xff08;QThread#xff09;简介环境项目结构配置编译环境代码 CMakeQT大漠插件的桌面应用开发#xff08;QThread#xff09;
简介 在CMakeQT大漠插件的桌面应用开发中已经给出了QT配合大漠插件开发桌面应用的样例 不过由于主… 文章目录 CMakeQT大漠插件的桌面应用开发QThread简介环境项目结构配置编译环境代码 CMakeQT大漠插件的桌面应用开发QThread
简介 在CMakeQT大漠插件的桌面应用开发中已经给出了QT配合大漠插件开发桌面应用的样例 不过由于主窗口的UI操作和大漠的调用是在一个线程里面的所以当大漠调用时间过长时会出现UI界面卡顿的现象 我们可以利用子线程处理耗时操作处理完后再由主线程UI线程更新界面这样界面就不会出现卡顿。 在这里我们将会用到QThread调整后的QT主线程与子线程交互逻辑图如下 交互逻辑描述 当点击“注册”选项时会发出regDM信号子线程接收到该信号会执行MyMainWorker中的doRegDM方法执行完成后会发出regDMReady信号主线程接收到该信号会执行更新UI的操作当点击“搜索”按钮时同理当点击“截图”按钮时同理
环境
版本/规范备注平台win32操作系统为Windows10CMake3.27.8CLion自带C17ToolchainVisualStudio 2022只用其工具链记得先安装好QT5.12.12安装时选择msvc2017不要64位的DM7.2353CLion2023.3.2你也可以用其他IDE工具
启动IDE时记得以管理员模式启动
项目结构
新建一个项目 qt_dm_demo_x_02目录同CMakeQT大漠插件的桌面应用开发中一致会多出MyMainWorker用于处理子线程逻辑
qt_dm_demo_x_02 # 项目目录
-- ......
--MyMainWorker.cpp
--MyMainWorker.h
-- ......配置编译环境
其他同CMakeQT大漠插件的桌面应用开发中一致CMakeLists.txt 文件中生成可执行文件时会多出MyMainWorker.cpp、MyMainWorker.h
# 生成可执行文件
add_executable(${PROJECT_NAME} main.cppstrutils.cpp strutils.hdmutil.cpp dmutil.hmymainwindow.cpp mymainwindow.h mymainwindow.uiMyMainWorker.cpp MyMainWorker.h
)代码
dmutil.h、dmutil.cpp、strutils.h、strutils.cpp、mymainwindow.ui、main.cpp同CMakeQT大漠插件的桌面应用开发中一致mymainwindow.h
#ifndef QT_DM_DEMO_X_MYMAINWINDOW_H
#define QT_DM_DEMO_X_MYMAINWINDOW_H#include QMainWindow
#include QTextEdit
#include QThread#include dmutil.hQT_BEGIN_NAMESPACE
namespace Ui { class MyMainWindow; }
QT_END_NAMESPACEclass MyMainWindow : public QMainWindow {
Q_OBJECTQThread workerThread;
public:explicit MyMainWindow(QWidget *parent nullptr);~MyMainWindow() override;public:void showInfo(const QString message, const QString title 提示);void showWarn(const QString message, const QString title 告警);signals:void regDM(Idmsoft **pDm);void findWindow(Idmsoft *pDm, const QString title);void captureWindow(Idmsoft *pDm, const long hwnd);public slots:void showMessageBox(bool result, const QString message);void showTable(bool result, const QString msg, const vectorMyWindow windowVec);private:Ui::MyMainWindow *ui;Idmsoft *pCommonDm nullptr;
};#endif //QT_DM_DEMO_X_MYMAINWINDOW_Hmymainwindow.cpp
// You may need to build the project (run Qt uic code generator) to get ui_MyMainWindow.h resolved#include QFont
#include QHeaderView
#include QMessageBox
#include QPushButton
#include QAction
#include QString
#include QTableWidgetItem
#include QObject
#include QVector
#include iostream
#include mymainwindow.h
#include ui_MyMainWindow.h
#include MyMainWorker.husing namespace std;MyMainWindow::MyMainWindow(QWidget *parent) :QMainWindow(parent), ui(new Ui::MyMainWindow) {ui-setupUi(this);qRegisterMetaTypeQVectorint(QVectorint);qRegisterMetaTypevectorMyWindow(vectorMyWindow);// Init ViewssetFixedSize(1280, 720);ui-tableWidget-setColumnCount(3);ui-tableWidget-setHorizontalHeaderLabels(QStringList() 进程ID 句柄 标题);ui-tableWidget-horizontalHeader()-setStretchLastSection(true); // 最后一列自动铺满表格// ui-tableWidget-horizontalHeader()-setSectionResizeMode(1, QHeaderView::Stretch);ui-tableWidget-horizontalHeader()-setHighlightSections(false);ui-tableWidget-horizontalHeader()-setStyleSheet(QHeaderView::section{background:gray;});ui-tableWidget-setSelectionMode(QAbstractItemView::SingleSelection);QFont font ui-tableWidget-horizontalHeader()-font();font.setBold(true);ui-tableWidget-horizontalHeader()-setFont(font);ui-tableWidget-setStyleSheet(QTableWidget::item:hover { background-color: lightblue; });ui-tableWidget-setEditTriggers(QAbstractItemView::NoEditTriggers); // 禁止编辑ui-tableWidget-setSelectionBehavior(QAbstractItemView::SelectRows); // 选中整行// Init Listenerauto worker new MyMainWorker;worker-moveToThread(workerThread);connect(workerThread, QThread::finished, worker, QObject::deleteLater);// 注册大漠connect(ui-actionReg, QAction::triggered, [this]() {ui-actionReg-setEnabled(false);emit this-regDM(this-pCommonDm);});connect(this, MyMainWindow::regDM, worker, MyMainWorker::doRegDM);connect(worker, MyMainWorker::regDMReady, this, MyMainWindow::showMessageBox);// 查找窗口connect(ui-btnQuery, QPushButton::clicked, [this]() {ui-btnQuery-setEnabled(false);emit this-findWindow(this-pCommonDm, ui-edtTitle-text());});connect(this, MyMainWindow::findWindow, worker, MyMainWorker::doFindWindow);connect(worker, MyMainWorker::findWindowReady, this, MyMainWindow::showTable);// 截图connect(ui-btnCapture, QPushButton::clicked, [this]() {ui-btnCapture-setEnabled(false);// 获取选中行的句柄列的字段const QListQTableWidgetItem * selectedItems ui-tableWidget-selectedItems();if (selectedItems.size() 2) {QTableWidgetItem *item selectedItems.at(1);const QString hwnd item-data(Qt::DisplayRole).toString();bool res false;long hwndL hwnd.toLong(res, 0);cout res endl;if (res) {emit this-captureWindow(this-pCommonDm, hwndL);} else {ui-btnCapture-setEnabled(true);this-showWarn(选中行的窗口句柄解析异常);}} else {ui-btnCapture-setEnabled(true);this-showWarn(请选中列表中的其中一行);}});connect(this, MyMainWindow::captureWindow, worker, MyMainWorker::doCaptureWindow);connect(worker, MyMainWorker::captureWindowReady, this, MyMainWindow::showMessageBox);workerThread.start();
}MyMainWindow::~MyMainWindow() {delete ui;workerThread.quit();workerThread.wait();
}void MyMainWindow::showInfo(const QString message, const QString title) {QMessageBox::information(this, title, message);
}void MyMainWindow::showWarn(const QString message, const QString title) {QMessageBox::critical(this, title, message);
}void MyMainWindow::showMessageBox(const bool result, const QString message) {ui-actionReg-setEnabled(true);ui-btnCapture-setEnabled(true);if (result) {this-showInfo(message);} else {this-showWarn(message);}
}void MyMainWindow::showTable(const bool result, const QString msg, const vectorMyWindow windowVec) {ui-btnQuery-setEnabled(true);if (result) {auto rowNum windowVec.size();ui-tableWidget-setRowCount(rowNum);for (int i 0; i rowNum; i) {const MyWindow item windowVec[i];ui-tableWidget-setItem(i, 0, new QTableWidgetItem(QString::number(item.processId)));ui-tableWidget-setItem(i, 1, new QTableWidgetItem(QString::number(item.hwnd)));ui-tableWidget-setItem(i, 2, new QTableWidgetItem(QString::fromStdWString(item.title)));}} else {this-showWarn(msg);}
}MyMainWorker.h
#ifndef QT_DM_DEMO_X_MYMAINWORKER_H
#define QT_DM_DEMO_X_MYMAINWORKER_H#include QObject
#include dmutil.hclass MyMainWorker: public QObject {
Q_OBJECT
signals:void regDMReady(const bool result, const QString msg);void findWindowReady(const bool result, const QString msg, const vector MyWindow windowVec);void captureWindowReady(const bool result, const QString msg);public slots:/*** 注册大漠* param pDm 大漠插件待赋值*/void doRegDM(Idmsoft **pDm);/*** 查询匹配的窗口* param pDm 大漠插件* param title 窗口标题模糊查询*/void doFindWindow(Idmsoft *pDm, const QString title);/*** 对窗口截图* param pDm 大漠插件* param hwnd 窗口句柄*/void doCaptureWindow(Idmsoft *pDm, long hwnd);
};#endif //QT_DM_DEMO_X_MYMAINWORKER_HMyMainWorker.cpp
#include iostream#include MyMainWorker.husing namespace std;void MyMainWorker::doRegDM(Idmsoft **pDm) {cout Initial DM ............ endl;*pDm initialDMAndRegVIP();if (*pDm nullptr) {cout Initial DM Failed endl;emit this-regDMReady(false, DM 注册失败);return;}cout Initial DM Successful endl;cout endl;emit this-regDMReady(true, DM 注册完成);
}void MyMainWorker::doFindWindow(Idmsoft *pDm, const QString title) {vectorMyWindow windowVec;if (pDm nullptr) {cout this-pCommonDm nullptr endl;emit this-findWindowReady(false, 请先在菜单中完成注册, windowVec);return;}// 找一下包含title的窗口getMatchedWindows(windowVec, pDm, title.toStdWString());if (windowVec.empty()) {cout can not find such window endl;emit this-findWindowReady(false, 没有找到包含该标题的窗口, windowVec);return;}emit this-findWindowReady(true, 成功, windowVec);
}void MyMainWorker::doCaptureWindow(Idmsoft *pDm, long hwnd) {if (pDm nullptr) {cout this-pCommonDm nullptr endl;emit this-captureWindowReady(false, 请先在菜单中完成注册);return;}// 绑定窗口句柄long dmBind pDm-BindWindowEx(hwnd,normal,normal,normal,,0);if (dmBind 1) {// 恢复并激活指定窗口置顶窗口pDm-SetWindowState(hwnd, 12);pDm-SetWindowState(hwnd, 8);pDm-delay(600);// 延迟一下截图存到相对路径wstring filename wstring(L./capture_window_).append(std::to_wstring(hwnd)).append(L.bmp);long retCap pDm-Capture(0, 0, 2000, 2000, filename.c_str());if (retCap ! 1) {cout capture failed endl;emit this-captureWindowReady(false, 截图失败);} else {cout capture success endl;emit this-captureWindowReady(true, QString::fromStdWString(L截图成功保存地址为 filename));}// 取消置顶窗口pDm-SetWindowState(hwnd, 9);} else {cout DM BindWindow failed endl;emit this-captureWindowReady(false, 绑定窗口异常);}pDm-UnBindWindow();
}