从外部类打印到MainWindow的元素

时间:2013-08-02 14:22:29

标签: c++ qt

我创建了一组监视外部应用程序的watcher / helper类,我希望这些类在更改时打印到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中创建这个线程,但我更喜欢在main中使用它。将StatePrinter类链接到MainWindow的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

你可以让你的观察者类成为一个QObject本身,将它推入一个线程,当它“注意到”你想要用日志信息作为信号参数记录的变化时,让它发出信号。

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

QThread* thread = new QThread();
ui->moveToThread(thread);

//Create the needed connections

thread->start();

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

答案 1 :(得分:1)

你有几个问题:

  1. 在QApplication实例之前创建小部件
  2. runnerThread.join调用将在进入Qt事件循环之前阻塞主Qt线程 - 因此您的GUI将被冻结
  3. 您应该实现通知系统以监视boost线程的终止。但更好的解决方案是使用Qt线程。

    1. 你应该创建第一类 - 带有必要信号的“观察者”。
    2. 然后使用UI逻辑和必要的插槽创建第二个类
    3. 然后将信号连接到插槽
    4. 利润!
    5. 查看有关QThread的Qt文档 - 有简单的示例。