【问题标题】:Use QT MainWindow in worker thread在工作线程中使用 QT MainWindow
【发布时间】:2017-10-26 00:44:35
【问题描述】:

我必须管理一个由更多 udp 通道消息更新的 MainWindow。此外,读取配置文件,我必须显示或不显示主窗口,如果不管理/调度/过滤 udp 消息到另一个应用程序。是否可以定义一个引擎类来管理通信并更新 Mainwindow(如果显示)?我如何管理主窗口?也许使用单例? 我会做什么(伪代码):

main.cpp:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Engine app();
    app.run();

    return a.exec();
} 

Engine.cpp

Engine::Engine( QObject *parent):
    QObject(parent)
{
   show_mainwindow = false;
   thread          = new QThread();
   Worker          = new Worker();

   // Filter/Dispatch
   Worker->moveToThread(thread);
   connect(Worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
   connect(thread, SIGNAL(started()), Worker, SLOT(process()));
   connect(Worker, SIGNAL(finished()), thread, SLOT(quit()));
   connect(Worker, SIGNAL(finished()), Worker, SLOT(deleteLater()));
   connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
   thread->start();

   // Message Receiver (more)
   UdpRecvr = new Receiver();
   connect(UdpRecvr, SIGNAL(receivedMsg(const QByteArray)), udpManager, SLOT(processMsg(const QByteArray)));

     //Mainwindow Singleton used to update with SIGNAL/SLOT
     WINDOWINSTANCE = MainWindow::GetInstance();

    if(show_mainwindow)
    {
        WINDOWISTANCE->show();
    }
}

在 UdpRecvr 类中,我也会使用 MainWindow Singleton。我已经读过使用带有 SIGNAL/SLOT 的单例是线程安全的。这是一个合适的设计解决方案吗? 提前致谢。

【问题讨论】:

  • 不推荐使用线程工作者。如果您使用基于任务的线程会更好(检查 QtConcurrent)

标签: c++ multithreading qt


【解决方案1】:

我通常在 MainWindow 中启动一个对话线程,并将 worker 的 SIGNAL 连接到 window 的 SLOT。

void MainGUI::startServerSockets() {
    serverSocket = new ServerSocket(cfg_robotPort);
    //serverSocket->setDebugLevel(debugLevel);
    ssocketThread = new QThread(this);
    connect(ssocketThread, SIGNAL(started()), serverSocket, SLOT(run()));
    connect(ssocketThread, SIGNAL(finished()), serverSocket, SLOT(deleteLater()));

    connect(serverSocket, SIGNAL(socketRead(const QString &)), this, SLOT(robotSocketRead(const QString &)));

    serverSocket->moveToThread(ssocketThread);
    ssocketThread->start();
} 

在worker中,您可以检查MainWindow是否可见,然后升起SIGNAL,否则与其他应用程序对话。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多