QT 多线程 GUI,允许同时更新更多元素
QT Multithread GUI, allowing to update more elements simultaneously
我的程序有 3 个具有不同功能的选项卡,我今天注意到这个问题:在第三个选项卡中启动功能时 运行 在单独的线程中但更新此选项卡上的 QPlainText 小部件(有时几秒钟一次) ,有时每次更新都不到一秒钟,例如需要一分钟,比如加载进度条)我不能在另一个选项卡上使用功能和小部件,尤其是当我必须在单击开始按钮之前向 lineEdit 小部件输入一些文本时 -这是不可能的,因为我立即从 lineEdit 中退出(或者我必须用鼠标单击它并快速输入一个字符)。我从 QT 教程和其他站点知道 GUI 在一个主线程中是 运行,但我想知道如果这是真正的问题,那么像 KDE 这样的 Linux 这样的大型项目是如何编写的。如何让它不阻塞?
//编辑
所以我正在使用 QTabWidget 但没关系,在 Tab3 上我正在启动新线程,它发出一些 API 请求和计算,然后发出信号以更新 QPlainTextEdit:
void QtWidgetsApplication1::on_pushButton_2_clicked() {
mThread = new QThread;
worker = new BinconThreadWorker;
worker->Stop = false;
QObject::connect(mThread, SIGNAL(started()), worker, SLOT(process()));
QObject::connect(worker, SIGNAL(valueChanged(std::string)), this, SLOT(onValueChanged(std::string)));
QObject::connect(worker, SIGNAL(valueSecChanged(std::string)), this, SLOT(onValueSecChanged(std::string)));
QObject::connect(worker, SIGNAL(finished()), mThread, SLOT(quit()));
QObject::connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
QObject::connect(mThread, SIGNAL(finished()), mThread, SLOT(deleteLater()));
worker->moveToThread(mThread);
mThread->start();
}
void QtWidgetsApplication1::onValueChanged(std::string s) {
ui.plainTextEdit->appendPlainText(QString::fromStdString(s));
ui.plainTextEdit->verticalScrollBar()->setValue(maximumHeight());
}
void QtWidgetsApplication1::onValueSecChanged(std::string s) {
ui.plainTextEdit->setFocus();
QTextCursor storeCursorPos = ui.plainTextEdit->textCursor();
ui.plainTextEdit->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
ui.plainTextEdit->moveCursor(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
ui.plainTextEdit->moveCursor(QTextCursor::End, QTextCursor::KeepAnchor);
ui.plainTextEdit->textCursor().removeSelectedText();
ui.plainTextEdit->textCursor().deletePreviousChar();
ui.plainTextEdit->setTextCursor(storeCursorPos);
ui.plainTextEdit->appendPlainText(QString::fromStdString(s));
ui.plainTextEdit->verticalScrollBar()->setValue(maximumHeight());
}
与此同时,我想在 Tab2 上做其他事情,其中 QLineEdit 小部件和按钮在此选项卡上执行某些操作,但是当我单击 QLineEdit 小部件时,光标消失所以我无法输入任何文本,因为 QPlainTextEdit Tab3 上的正在接收信号,因此它会更新其内容,并在我尝试使用它时停用另一个选项卡上的 QLineEdit。只有当 QPlainTextEdit 在短时间间隔更新时才会发生,小于 1s。
问题只是语句...
ui.plainTextEdit->setFocus();
在 QtWidgetsApplication1::onValueSecChanged
中。它 'steals' 来自当前焦点持有者的输入焦点——在你的例子中是 QLineEdit
。只需删除该行,事情就会按预期进行。
我的程序有 3 个具有不同功能的选项卡,我今天注意到这个问题:在第三个选项卡中启动功能时 运行 在单独的线程中但更新此选项卡上的 QPlainText 小部件(有时几秒钟一次) ,有时每次更新都不到一秒钟,例如需要一分钟,比如加载进度条)我不能在另一个选项卡上使用功能和小部件,尤其是当我必须在单击开始按钮之前向 lineEdit 小部件输入一些文本时 -这是不可能的,因为我立即从 lineEdit 中退出(或者我必须用鼠标单击它并快速输入一个字符)。我从 QT 教程和其他站点知道 GUI 在一个主线程中是 运行,但我想知道如果这是真正的问题,那么像 KDE 这样的 Linux 这样的大型项目是如何编写的。如何让它不阻塞?
//编辑 所以我正在使用 QTabWidget 但没关系,在 Tab3 上我正在启动新线程,它发出一些 API 请求和计算,然后发出信号以更新 QPlainTextEdit:
void QtWidgetsApplication1::on_pushButton_2_clicked() {
mThread = new QThread;
worker = new BinconThreadWorker;
worker->Stop = false;
QObject::connect(mThread, SIGNAL(started()), worker, SLOT(process()));
QObject::connect(worker, SIGNAL(valueChanged(std::string)), this, SLOT(onValueChanged(std::string)));
QObject::connect(worker, SIGNAL(valueSecChanged(std::string)), this, SLOT(onValueSecChanged(std::string)));
QObject::connect(worker, SIGNAL(finished()), mThread, SLOT(quit()));
QObject::connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
QObject::connect(mThread, SIGNAL(finished()), mThread, SLOT(deleteLater()));
worker->moveToThread(mThread);
mThread->start();
}
void QtWidgetsApplication1::onValueChanged(std::string s) {
ui.plainTextEdit->appendPlainText(QString::fromStdString(s));
ui.plainTextEdit->verticalScrollBar()->setValue(maximumHeight());
}
void QtWidgetsApplication1::onValueSecChanged(std::string s) {
ui.plainTextEdit->setFocus();
QTextCursor storeCursorPos = ui.plainTextEdit->textCursor();
ui.plainTextEdit->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
ui.plainTextEdit->moveCursor(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
ui.plainTextEdit->moveCursor(QTextCursor::End, QTextCursor::KeepAnchor);
ui.plainTextEdit->textCursor().removeSelectedText();
ui.plainTextEdit->textCursor().deletePreviousChar();
ui.plainTextEdit->setTextCursor(storeCursorPos);
ui.plainTextEdit->appendPlainText(QString::fromStdString(s));
ui.plainTextEdit->verticalScrollBar()->setValue(maximumHeight());
}
与此同时,我想在 Tab2 上做其他事情,其中 QLineEdit 小部件和按钮在此选项卡上执行某些操作,但是当我单击 QLineEdit 小部件时,光标消失所以我无法输入任何文本,因为 QPlainTextEdit Tab3 上的正在接收信号,因此它会更新其内容,并在我尝试使用它时停用另一个选项卡上的 QLineEdit。只有当 QPlainTextEdit 在短时间间隔更新时才会发生,小于 1s。
问题只是语句...
ui.plainTextEdit->setFocus();
在 QtWidgetsApplication1::onValueSecChanged
中。它 'steals' 来自当前焦点持有者的输入焦点——在你的例子中是 QLineEdit
。只需删除该行,事情就会按预期进行。