QT - 强制对象处理传入信号

QT - force an object to process incoming signals

我想知道如何告诉 QObject 处理所有信号并调用与它们关联的槽。这是我遇到的具体问题,以便更好地描述问题:

我的程序由三个 Qthread 组成:Main、Communication 和 Input。

通信线程通过网络处理通信,输入线程处理用户输入,两者都有几个到主线程的信号槽连接。每当网络事件发生时,或者每当用户输入命令行命令时,都会调用来自相应线程的信号,然后激活主线程中适当的连接插槽。主线程的作用就是处理这些事件。我的代码如下所示:

QApplication a(argc, argv);
CommObj co; //inherits from QThread
co.start();  //Starts the thread
InputObj io; //inherits from QThread
io.start(); //Starts the thread
MainObj u(&co,&io);
return a.exec();

现在,我要实现的是主线程不执行到最后一行。 我的意图是在 MainObj 的构造函数中调用一个方法 运行() ,它将按照以下方式做一些事情:

void run ()
{
 forever
 {
  //process all signals..
 }
}

但是,我不知道如何实现所有信号部分的处理。非常欢迎任何有关如何完成此操作的建议(包括解决方法)。

你需要的是processEvents功能。例如,如果您不希望用户能够与小部件交互,但希望图形更新,请使用

processEvents(QEventLoop::ExcludeUserInputEvents);

详情见documentation

这完全没有必要。 a.exec()运行是一个事件循环,它将接收和处理其他线程发送的事件。

当由于在不同线程中发出信号而调用槽时,Qt 将 QMetaCallEvent 发送到接收器对象。 QObject::event方法可以根据事件中的数据重新合成slot调用

因此,您什么都不用做。 a.exec() 为所欲为。随意从 MainObj 的构造函数中调用它,如 qApp->exec()QEventLoop loop; loop.exec(),但这是相当糟糕的设计。

真题是:

  1. 为什么需要 MainObj 的构造函数来旋转事件循环?

  2. 您在 io 处理哪种 "user input"?您无法从该线程访问任何 GUI 对象。

  3. 如果您使用 Qt 的网络,为什么要从 QThread 派生?您绝对不想这样做 - 除非您旋转事件循环,否则它不会起作用,因此您最好使用 QThread 而不做任何更改。好吧,为了安全起见,您只需要使线程可破坏,所以:

    class Thread {
      using QThread::run; // make it final
    public:
      Thread(QObject * parent = 0) : QThread(parent) {}
      ~Thread() { requestInterruption(); quit(); wait(); }
    };
    

    无论如何,通过不使用旋转事件循环的标准 QThread,通信将是一种方式。此类线程中的任何内容都无法对来自其他线程的信号做出反应。

您需要重构如下:

  1. 如上使用Threadclass。随时被破坏是安全的

  2. 具有 运行 异步使用 signals/slots/timers 的工作对象。

  3. 将构造的 worker 移动到它们的线程。