码迷,mamicode.com
首页 > 编程语言 > 详细

QT 线程(2)--- QLogWidget 未完待续

时间:2021-02-17 14:52:00      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:pop   locker   code   div   operation   static   ptr   sig   ++   

  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 };
#include "QLogWidget.h"

/* ... here is the expensive or blocking operation ... */
void Worker::doWork(const QString& parameter) 
{
    static int count = 0;
    //qDebug() << "In do work ThreadId:" << QThread::currentThreadId();
    if (!pQueue) return;
    if (CMD_PUSH == parameter) {
        //QThread::usleep(5);
        qDebug() << QString("push:%1").arg(count);
        pQueue->enQueue(QString("%1").arg(count++));

        emit resultReady(QString("%1_%2").arg(parameter).arg(count));
    }

    if (CMD_POP == parameter) {
        QThread::usleep(100);
        auto s = pQueue->deQueue();
        qDebug() << QString("pop:%1").arg(s);

        emit resultReady(QString("%1_%2").arg(parameter).arg(s));
    }  
}

void Controller::handleResults(const QString& msg)
{
   // qDebug() <<"---Controller::handleResults(const QString& msg)-------" <<msg;
    if (!pLogWidget) return;
    QString cmd = msg.split("_", QString::SkipEmptyParts).at(0);
    if (cmd == CMD_PUSH)  handleResultsPush(msg);
    if (cmd == CMD_POP)   handleResultsPop(msg); 
}

QLogWidget::QLogWidget(QWidget *parent) : QMainWindow(parent)
{
    ui.setupUi(this);
}

  

#include "QLogWidget.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    qDebug() << "Main thread id is:" << QThread::currentThreadId(); //输出主线程ID  
    
    QLogWidget* w = new QLogWidget();
    w->show();
    
    LogQueue<>* pLog = new LogQueue<>();
    
    Controller* pWriter = new Controller(pLog,w);
    Controller* pReader = new Controller(pLog,w); 
    QObject::connect(pWriter, &Controller::handleResultsPush, w,&QLogWidget::addPushLog);
    QObject::connect(pReader, &Controller::handleResultsPop,  w,&QLogWidget::addPopLog);

    const int MAX  = 1E4;
    for (int i = 0; i < MAX; i++) {  pWriter->operate(CMD_PUSH);  }
    for (int i = 0; i < MAX; i++) {  pReader->operate(CMD_POP);   }

    return a.exec();
}

  2.效果

技术图片

 

 3.其他

技术图片

 

QT 线程(2)--- QLogWidget 未完待续

标签:pop   locker   code   div   operation   static   ptr   sig   ++   

原文地址:https://www.cnblogs.com/sansuiwantong/p/14402828.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!