Qt - 在单独的线程中运行函数
Qt - Run function in Separate Thread
我有一个由按钮单击触发的函数。执行时,它会迭代给定目录中的文件,读取每个文件,然后通过套接字连接将内容发送到客户端。对于发送的每个文件,内容将写回 GUI。还有一个按钮用于停止迭代。截至目前,我正在主线程中处理此问题,但是,正如预期的那样,gui 变得有些无响应。我尝试在另一个线程中执行该函数,但是,我的实现比在主线程中运行更糟糕!见下文,所有内容都位于同一类中。处理此问题的最佳方法是什么?
private:
QThread mSendDirectoryFilesThread;
private slots:
void onSendDirectoryFilesClicked();
void onStopSendingDirectoryFilesClicked();
void sendDirectoryFiles();
在类实例化上连接插槽等
moveToThread(&mSendDirectoryFilesThread);
connect(&mSendDirectoryFilesThread, SIGNAL(started()), this, SLOT(sendDirectoryFiles()));
发送按钮点击信号
void MainView::onSendDirectoryFilesClicked()
{
mSendDirectoryFilesThread.start();
}
发送功能
void MainView::sendDirectoryFiles() {
QDir packetDir(ui->txtSelectedDirectory->text());
packetDir.setNameFilters(QStringList() << "*.xml");
QStringList dirFiles = packetDir.entryList();
if (dirFiles.count() > 0) {
ui->btnStopSendingDirectoryFiles->setEnabled(true);
foreach (QString f, dirFiles) {
QApplication::processEvents();
QFile file(ui->txtSelectedDirectory->text() + QDir::separator() + f);
mDocToSend = getFileXML(file);
if (mDocToSend.isDocument()) {
if (mSocket.sendDoc(mDocToSend)) {
addToPacketLog(mDocToSend.toString(), "SENT");
QThread::sleep(ui->txtTransmitInterval->text().toInt());
} else {
qDebug() << "Nothing to send";
}
}
}
}
}
停止按钮点击信号
void MainView::onStopSendingDirectoryFilesClicked()
{
mSendDirectoryFilesThread.exit(0);
}
MainView::sendDirectoryFiles
不会在工作线程中执行,因为connect
默认使用Qt::AutoConnection
,这意味着该函数在 slot 对象的线程中调用,即this
在您的示例中。您可以通过显式选择Qt::DirectConnection
来更改默认行为:
connect(&mSendDirectoryFilesThread, SIGNAL(started()), this, SLOT(sendDirectoryFiles()), Qt::DirectConnection);
进一步考虑
请注意,
MainView::sendDirectoryFiles
应该是线程安全的,但事实并非如此。例如,您正在通过调用ui->btnStopSendingDirectoryFiles->setEnabled(true);
来更改 GUI,这是不允许的。您可能还希望在
MainView::sendDirectoryFiles
结束时调用mSendDirectoryFilesThread.exit(0)
,否则如果不先显式停止操作,您将无法执行两次操作。如 H. Gomaa 指出的那样,使用
QtConcurrent::run
可能是一个更清晰的解决方案,但调用的方法仍然应该是线程安全的。您可以考虑将新信号添加到派生类
QThread
中,该类调用操作而不是启动/停止线程。使用QThreadPool
和QRunnable
任务也可能是一个好主意。
- 无法获取菜单选择以运行函数.C++
- 为什么std::async使用同一个线程运行函数
- MINGW - 正确运行函数所需的 cdecl
- 如何在 C 中使用空的 main() 方法运行函数?
- 运行函数作为 constexpr 和不作为 constexpr
- 如何在全局变量的构造函数之前运行函数
- 在 Cap'n Proto RPC 服务器中定期运行函数
- 为什么当我在 c++ 中运行函数时,我的代码显示数字 53
- CLang:在 std::thread 中运行函数会导致结构创建BAD_ACCESS
- 如何使用 TBB 在单个线程中运行函数
- 我在运行函数 GetVolumeInformation() 时得到非常随机的结果
- 如何使用 boost::asio io_service 运行函数异步
- Qt - 在其他线程上运行函数
- 在一组模板化对象上运行函数
- pybind11:属性错误:尝试从 py 文件运行函数时,模块'XXX'没有属性'YYY'
- 添加按钮以通知运行函数的通知
- 如何在程序后台运行函数(特别是自动保存函数)?QT / C++
- Qt - 在单独的线程中运行函数
- 如何在单独的线程上运行函数(如果线程可用)
- 如何发出编译和运行C++函数的 LLVM IR