QT分叉
使用QtCreator为软件创建更高的界面。 基本上有一组按钮来调整和输入,一个启动和停止作业 buttons,我的问题来自一个无限循环,它冻结了显示,所以我想到了使用fork(),这样循环就必须与主程序竞争,而不是消耗整个资源(没有多线程),但是程序崩溃了:QT分叉,qt,fork,Qt,Fork,使用QtCreator为软件创建更高的界面。 基本上有一组按钮来调整和输入,一个启动和停止作业 buttons,我的问题来自一个无限循环,它冻结了显示,所以我想到了使用fork(),这样循环就必须与主程序竞争,而不是消耗整个资源(没有多线程),但是程序崩溃了: [xcb] Unknown sequence number while processing queue [xcb] Most likely this is a multi-threaded client and XInitThreads
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not
been called
[xcb] Aborting, sorry about that.
a.out: ../../src/xcb_io.c:274: poll_for_event: Assertion
`!xcb_xlib_threads_sequence_lost' failed.
调用循环的函数称为“开”,“关”应该退出分叉进程
//in button 'ON' func
ps = fork();
if(getpid() == ps)
{
while(1)
{
strcpy(word, charset(minlength, maxlength, N));
ui->pass->setText(word);//operation on the display
....SNIP
}
}
//In button 'OFF' func
if(getpid() == ps)
exit(0);
我真的想问的是,怎样才能正确地开始一段时间(1),并能够在不使用QT冻结窗口的情况下中断、退出或从中返回,谢谢。您可能会在这里崩溃:
ui->pass->setText(word);//operation on the display
与在Qt中一样,您不能直接从非UI线程更改UI。仅来自信号和插槽机制
不冻结UI的正确方法显然是在另一个线程中计算冗长的操作
您可以通过以下几种方式实现这一点:
一种是通过对QObject类进行子分类来创建“worker对象”,它将执行所有繁重的操作。您可以创建新的QThread
对象,该对象应该在您需要对象的时候一直存在。并使用QObject::moveToThread
方法将创建的对象移动到新线程。要控制worker对象,您应该从对象发送信号,并通过信号槽机制调用其插槽。如果您直接调用它们,它们将在调用线程中执行(所以不要在UI线程中执行类似worker->startHeavyJob();的操作)。而是在UI中发出信号(emit sigStartHeavyStuff();),并将其连接到工作对象的插槽(slotDoHeavyStuff();)
如果您不想为此烦恼(如果操作非常小)
-您可以使用在无限while循环中处理UI事件循环中的事件
另一种方法是使用框架在单独的线程中运行函数,该线程管理自身。线程取自线程池,由Qt管理。这种方法看起来像是您想要做的事情。尽管您仍然只能通过信号和插槽访问UI对象。我看到了导致您冻结的代码中的一个大问题:在循环中,您从不让Qt处理任何东西。您需要允许Qt运行它的事件循环。最简单的方法是在循环中使用
QApplication::processEvents()
我也不喜欢while(1)
循环,原因有二。首先,它可以吃掉等待事情发生的机器循环。我怀疑您是否真的需要尽可能快地运行代码,您可能会在循环中睡上一觉
另一个问题是很难突破。更干净的方法应该是这样的
void MyClass::on_pushButton_ON_clicked()
{
MyClass::done = false; // this is a class attribute
while (!MyClass::done) {
QApplication::processEvents();
//...
}
}
void MyClass::on_pushButton_OFF_clicked()
{
MyClass::done = true;
}
当你说“无多线程”时,你实际上是在通过分叉一个进程(内存空间+线程)来生成更多线程。我真的很失望,因为我不想深入到QTthreads的世界中,但是循环中包含的processEvents()例程修复了我的问题,谢谢。关于QtConcurrent::run()我必须这样使用我的成员函数:
QFuture p1=QtConcurrent::run(this,&MainWindow::loop)代码>从on_按钮on_clicked()功能调用。它必须是MainWindow的一个成员,这样我才不会弄乱Ui,这给我带来了极大的痛苦。只是关于睡眠操作的一个问题:它不会释放程序内部的资源,而只能用于其他进程,考虑到它仍然是单线程的事实?我进入了线程,这就引导我进入了我从未学习过的信号和插槽系统,所以感谢你的指导。