2015-05-06 2 views
2

Я использую QPlainTextEdit для отображения некоторого текста. Этот текст будет изменен (добавление) в другом потоке, чем Ui (основная) нить с передачей сигнала на виджетДоступ к потоку виджета Qt

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, но и строку в виде копии.

+0

пойдите для вашего второго подхода, беспокойтесь об эффективности, когда все работает, и ** действительно ** слишком медленно. –

+1

«Я думал о мьютексе, чтобы заблокировать сигнал записи» <--- Не нужно. Соединения сигналов/слотов автоматически «потокобезопасны». – Greenflow

+1

Проверьте свою документацию по Qt и выполните поиск: Qt :: QueuedConnection – Greenflow

ответ

1

По существу, если вы используете автоматическое или поставленное в очередь соединение (см. QObject::connect) при подключении сигнала от объекта, принадлежащего другому потоку (см. QObject::moveToThread) к виджету (который должен принадлежать основному потоку gui) , то излучение сигнала будет асинхронным вызовом «огонь и забвение». Вы также можете сделать синхронный вызов, указав, что это заблокированное подключение, но я не рекомендую его, если вы действительно этого не требуете.

Модель резьбы в Qt требует немного обернуть голову, но вы будете любить сигналы простоты и слоты в многопоточном коде и сколько фрагментов кода больше не потребуется защищать свои данные с помощью мьютексов.

Смежные вопросы