访问Qt小部件线程安全

时间:2015-05-06 18:05:47

标签: c++ multithreading qt

我使用QPlainTextEdit来显示一些文字。此文本将在ui(主)线程之外的另一个线程中修改(追加),并向小部件发送信号

connect(this, SIGNAL(addText(QString)), mUi->plainTextEditLog, SLOT(appendPlainText(QString)));

...
emit addText(QString::fromStdString(someString));
...

另一个线程正在读取此PlainTextEdit的文本并将其写入文件

QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
    return;
}
file.write(mUi->plainTextEditLog->toPlainText().toUtf8());
file.close();

据我所知,Qt小部件不是线程安全的。我想了一个互斥锁来锁定写入信号的发射,但是这不会真的锁定它,因为它只是异步发送信号。

我使用信号的原因是写入方法可以从多个线程调用,而互斥锁在这种情况下没有帮助,但信号完美无缺。

第二个想法是将文本存储在我的班级中并锁定互斥的字符串。但我不确定这是否非常有效,因为不仅需要修改明文而且字符串也是副本。

1 个答案:

答案 0 :(得分:1)

本质上,只要在将来自属于另一个线程的对象(请参阅QObject::connect)的信号连接到窗口小部件时(必须使用自动或排队连接(请参阅QObject::moveToThread)属于主要的gui线程),然后发出的信号将是一个异步的“即发即忘”调用。您也可以通过指定阻塞排队连接来使呼叫同步,但除非您确实需要,否则我不推荐它。

Qt中的线程模型需要花点时间,但您会逐渐喜欢简单信号和插槽提供多线程代码,以及多少代码将不再需要用互斥锁来保护他们的数据。 / p>