强制一个对象处理输入的信号



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

我的程序由三个qthread组成:Main, Communication and 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的构造函数中调用一个方法run(),它将沿着下面的行做一些事情:

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

但是,我不知道如何实现进程的所有信号部分。任何关于如何做到这一点的建议(包括变通方法)将是非常欢迎的。

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

当一个slot被调用时,由于一个信号在另一个线程中被发出,Qt将发送一个QMetaCallEvent给接收对象。QObject::event方法能够根据事件中的数据重新合成槽位调用。

因此,您不需要做任何事情。a.exec()做你想做的。您可以随意地从MainObj的构造函数中调用它,如qApp->exec()QEventLoop loop; loop.exec(),但这是相当糟糕的设计。

真正的问题是:

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

  2. 你在io中处理什么样的"用户输入"?你不能从这个线程访问任何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. 如上所述使用Thread类。随时销毁是安全的

  2. 让worker对象使用信号/插槽/定时器异步运行。

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

processEvents(QEventLoop::ExcludeUserInputEvents);

详情请参阅文档

最新更新