QT 线程(2)--- QLogWidget 未完待续
1:效果

2:代码:

1 #pragma once 2 3 #include <QtWidgets/QMainWindow> 4 #include "ui_QLogWidget.h" 5 #include <QQueue> 6 #include <QMutex> 7 #include <QWaitCondition> 8 #include <QMutexLocker> 9 #include <QThread> 10 #include <QDebug> 11 #include <QPushButton> 12 #include <QStringList> 13 14 #define CMD_PUSH "PUSH A MSG" 15 #define CMD_POP "POP A MSG" 16 17 template <typename T = QString> 18 class LogQueue 19 { 20 public: 21 explicit LogQueue() {} 22 23 inline void enQueue(const T& t) 24 { 25 QMutexLocker locker(&_mutex); 26 _queue.enqueue(t); 27 _unempty.wakeAll(); 28 } 29 inline T deQueue() 30 { 31 QMutexLocker locker(&_mutex); 32 while (_queue.size() == 0) 33 { 34 _unempty.wait(&_mutex); 35 } 36 return _queue.dequeue(); 37 } 38 inline void clear() 39 { 40 QMutexLocker locker(&_mutex); 41 _queue.clear(); 42 _unempty.wakeAll(); 43 } 44 45 private: 46 QQueue<T> _queue; 47 QMutex _mutex; 48 QWaitCondition _unempty; 49 }; 50 51 class Worker : public QObject 52 { 53 Q_OBJECT 54 public: 55 void setQueue(LogQueue<>* p) { pQueue = p; } 56 57 public slots: 58 void doWork(const QString& parameter); 59 signals: 60 void resultReady(const QString& result); 61 62 private: 63 LogQueue<>* pQueue; 64 }; 65 66 class QLogWidget : public QMainWindow 67 { 68 Q_OBJECT 69 70 public: 71 QLogWidget(QWidget* parent = Q_NULLPTR); 72 73 public slots: 74 void addPushLog(const QString& s) { 75 pushNum = s.split("_", QString::SkipEmptyParts).at(1).toInt(); 76 ui.spinBox_num->setValue(pushNum- popNum); 77 ui.progressBar->setValue(popNum * 100 / pushNum); 78 ui.plainTextEdit_push->appendPlainText(s); 79 } 80 void addPopLog(const QString& s) { 81 popNum = s.split("_", QString::SkipEmptyParts).at(1).toInt(); 82 ui.spinBox_num->setValue(pushNum - popNum); 83 ui.progressBar->setValue(popNum * 100 / pushNum); 84 ui.plainTextEdit_pop->appendPlainText(s); 85 } 86 87 88 private: 89 Ui::QLogWidgetClass ui; 90 int pushNum; 91 int popNum; 92 }; 93 94 95 class Controller : public QObject 96 { 97 Q_OBJECT 98 QThread workerThread; 99 100 public: 101 Controller(LogQueue<>* w1, QLogWidget* w2) : pLogQueue(w1), pLogWidget(w2){ 102 Worker* worker = new Worker; 103 worker->setQueue(pLogQueue); 104 worker->moveToThread(&workerThread); 105 connect(&workerThread,&QThread::finished ,worker,&QObject::deleteLater); 106 connect(this ,&Controller::operate,worker,&Worker::doWork); 107 connect(worker ,&Worker::resultReady,this ,&Controller::handleResults); 108 workerThread.start(); 109 } 110 ~Controller() { 111 workerThread.quit(); 112 workerThread.wait(); 113 } 114 115 public slots: 116 void handleResults(const QString&); 117 118 signals: 119 void operate(const QString&); 120 void handleResultsPush(const QString&); 121 void handleResultsPop(const QString&); 122 123 private: 124 LogQueue<>* pLogQueue; 125 QLogWidget* pLogWidget; 126 };

1 #include "QLogWidget.h" 2 3 /* ... here is the expensive or blocking operation ... */ 4 void Worker::doWork(const QString& parameter) 5 { 6 static int count = 1; 7 //qDebug() << "In do work ThreadId:" << QThread::currentThreadId(); 8 if (!pQueue) return; 9 if (CMD_PUSH == parameter) { 10 //QThread::usleep(5); 11 qDebug() << QString("push:%1").arg(count); 12 pQueue->enQueue(QString("%1").arg(count)); 13 14 emit resultReady(QString("%1_%2").arg(parameter).arg(count)); 15 count++; 16 } 17 18 if (CMD_POP == parameter) { 19 QThread::usleep(100); 20 auto s = pQueue->deQueue(); 21 qDebug() << QString("pop:%1").arg(s); 22 23 emit resultReady(QString("%1_%2").arg(parameter).arg(s)); 24 } 25 } 26 27 void Controller::handleResults(const QString& msg) 28 { 29 // qDebug() <<"---Controller::handleResults(const QString& msg)-------" <<msg; 30 if (!pLogWidget) return; 31 QString cmd = msg.split("_", QString::SkipEmptyParts).at(0); 32 if (cmd == CMD_PUSH) handleResultsPush(msg); 33 if (cmd == CMD_POP) handleResultsPop(msg); 34 } 35 36 QLogWidget::QLogWidget(QWidget *parent) : QMainWindow(parent) 37 { 38 ui.setupUi(this); 39 }

1 #include "QLogWidget.h" 2 #include <QtWidgets/QApplication> 3 4 int main(int argc, char *argv[]) 5 { 6 QApplication a(argc, argv); 7 qDebug() << "Main thread id is:" << QThread::currentThreadId(); //输出主线程ID 8 9 QLogWidget* w = new QLogWidget(); 10 w->show(); 11 12 LogQueue<>* pLog = new LogQueue<>(); 13 14 Controller* pWriter = new Controller(pLog,w); 15 Controller* pReader = new Controller(pLog,w); 16 QObject::connect(pWriter, &Controller::handleResultsPush, w,&QLogWidget::addPushLog); 17 QObject::connect(pReader, &Controller::handleResultsPop, w,&QLogWidget::addPopLog); 18 19 const int MAX = 1E3; 20 for (int i = 0; i < MAX; i++) { pWriter->operate(CMD_PUSH); } 21 for (int i = 0; i < MAX; i++) { pReader->operate(CMD_POP); } 22 23 return a.exec(); 24 }
3.其他
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通