gpt4 book ai didi

c++ - QT多线程和更新GUI

转载 作者:行者123 更新时间:2023-12-02 10:05:16 30 4
gpt4 key购买 nike

我目前正在将一个设计用于GTK GUI的现有代码库更新为QT,以便它可以实现多线程,因为这些功能需要数小时才能完成。

该代码库频繁调用函数display(std::string),以更新文本显示窗口小部件。我为新的QT版本重新定义了此功能:

在Display.cpp中:

void display(std::string output)
{
//
MainWindow * gui = MainWindow::getMainWinPtr(); //Gets instance of GUI
gui->DisplayInGUI(output); //Sends string to new QT display function
}

在MainWindow.cpp中:
void MainWindow::DisplayInGUI(std::string output)
{
//converts output to qstring and displays in text edit widget
}

void MainWindow::mainFunction(){
//calls function in existing codebase, which itself is frequently calling display()
}

void MainWindow::on_mainFunctionButton_released()
{
QFuture<void> future = QtConcurrent::run(this,&MainWindow::mainFunction);
}

如果我在新线程中运行main函数,则在该线程完成之前 display(std::string)不会更新GUI。我明白为什么; GUI只能在主线程中更新。其他所有功能均按预期运行。
我要实现的方法,但我不确定如何实现,即 display(std:string)将信号发送回主线程,以使用传递给display()函数的字符串来调用 MainWindow::DisplayInGUI(output_text)。我相信这是正确的做法,但是如果我错了,请纠正我。我想避免不惜一切代价更改现有代码库。

编辑:我应该补充一点,由于某些愚蠢的原因,完全出于我的控制,我被迫使用C++ 98(是的,我知道)

最佳答案

您必须安排执行UI调用的代码以在主线程中运行。我为此使用了一个简单易用的包装器:

#include <QApplication>
#include <QtGlobal>
#include <utility>

template<typename F>
void runInMainThread(F&& fun)
{
QObject tmp;
QObject::connect(&tmp, &QObject::destroyed, qApp, std::forward<F>(fun),
Qt::QueuedConnection);
}

现在,您可以在主线程中运行代码(在此示例中使用lambda,但其他可调用对象也可以运行),如下所示:
runInMainThread([] { /* code */ });

在您的情况下:
void display(std::string output)
{
runInMainThread([output = std::move(output)] {
MainWindow* gui = MainWindow::getMainWinPtr();
gui->DisplayInGUI(output);
});
}

或者,您可以保留 display()而不是包装对其的调用:
runInMainThread([str] { display(std::move(str)); );
std::move只是为了避免字符串的另一个副本而进行的优化,因为在这种情况下,您不应该通过引用传递字符串(一旦字符串对象超出范围,它将成为悬挂的引用。)

这不是高性能的线程间通信机制。每次调用都将导致构造一个临时的QObject和一个临时的信号/插槽连接。对于定期的UI更新,它已经足够了,它允许您在主线程中运行任何代码,而不必为各种UI更新操作手动设置信号/插槽连接。但是对于每秒数千个UI调用来说,这可能不是很有效。

关于c++ - QT多线程和更新GUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60512713/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com