从外部类打印到MainWindow的元素

Printing to an element of MainWindow from an outside class

本文关键字:元素 MainWindow 打印 从外部      更新时间:2023-10-16

我已经创建了一组监视外部应用程序的观察程序/帮助程序类,我希望在进行更改时将这些类打印到MainWindow ui中的日志窗口中。我的想法是在main中的一个线程中创建这个观察程序,但我不确定将它链接到我的MainWindow的最佳方式。我知道简单地按照下面的方式传递它是行不通的,但由于Qt的设计,我不确定正确的方法来做到这一点,如果有的话。一些研究向我表明,将MainWindow传递给外部班级并不合适,但我不确定有更好的方法。

int main(int argc, char *argv[])
{
    try {
        std::string host = "localhost";
        unsigned short port = 8193;
        MainWindow w;
        w.show();
        // Access class for the program that I am watching
        UserInterface ui(host, port);
        // StatePrinter class, which is registered in the UI and will print changes to MainWindow, ideally
        // would I be able to pass something in the StatePrinter constructor to accomplish my goal?
        ui.registerObserver(new StatePrinter(w));
        UiRunner runner(ui);
        boost::thread runnerThread(boost::ref(runner));
        w.show();
        QApplication a(argc, argv);
        runner.cancel();
        runnerThread.join();
        return a.exec();
    } catch(std::exception &ex) {
        // ...
    }
}

我想在MainWindow中制作这个线程是有可能的,但我更喜欢在主窗口中使用它。将StatePrinter类链接到MainWindow的最佳方式是什么?

您可以使您的观察者类本身成为QObject,将其推送到线程中,并使其在"注意到"您想要记录的更改时发出信号,并将日志信息作为信号参数。

然后,您可以在QThread中按如下方式推送此对象:

QThread* thread = new QThread();
ui->moveToThread(thread);
//Create the needed connections
thread->start();

根据需要,您可以将信号连接到线程的start()插槽,而不是直接调用它。(阅读本文,了解线程需要哪些连接,以便正确启动、停止和清理)。

您有几个问题:

  1. 在QApplication实例之前创建小部件
  2. runnerThread.join调用将在进入Qt事件循环之前阻塞主Qt线程,因此您的GUI将被冻结

您应该实现通知系统来监视boost线程的终止。但更好的解决方案是使用Qt线程。

  1. 您应该创建第一个类——具有必要信号的"观察者"
  2. 然后用UI逻辑和必要的插槽创建第二个类
  3. 然后将信号连接到插槽
  4. 利润

看看关于QThread的Qt文档——有一些简单的示例。