我使用 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 小部件不是线程安全的。我想到了一个互斥体来锁定写入信号发射,但这不会真正锁定它,因为它只是异步发送信号。
我使用信号的原因是可以从多个线程调用写入方法,在这种情况下互斥量没有帮助,但信号非常完美。
第二个想法是将文本也存储在我的类中并使用互斥锁定字符串。但我不确定这是否非常有效,因为不仅有必须修改的 plaintextedit,还有作为拷贝的字符串。
最佳答案
本质上,只要在将信号从属于另一个线程的对象(参见 QObject::connect)连接到小部件(必须属于主线程)时使用自动或排队连接(参见 QObject::moveToThread) gui 线程),然后发出信号将是一个异步的“即发即弃”调用。您还可以通过指定它是阻塞排队连接来使调用同步,但我不推荐这样做,除非您确实需要它。
Qt 中的线程模型需要一点时间来理解,但您会逐渐喜欢上多线程代码中信号和槽的简单性,以及有多少代码不再需要使用互斥锁来保护它们的数据。
关于c++ - 访问 Qt 小部件线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30084371/