Я нахожусь на этой неделе с проблемой, вызванной обновлением QPlainTextEdit. Я пытаюсь создать отдельно от окна QMainWindow Dialog с QPlainTextEdit внутри. Проблема начинается, когда я пытаюсь использовать сигнал appendHtml (также пытался с appendText), текст, который помещен, не отображается, если не отмечен мышью. Перекрашивание или обновление причины сбоя программы или отсутствие видимого действия.Как заставить Qt обновлять GUI из не основной темы
Упрощенный код QDialog с заголовком QPlainTextEdit:
namespace Ui {
class LogWindow;
}
class LogWriter: public QDialog
{
Q_OBJECT
QMutex print_lock;
public:
class Log{
Q_OBJECT
const static int MAX_SIZE = 100;
bool to_terminal;
QString color;
QMutex *print_lock;
QPlainTextEdit *text_place;
QVector< QPair<QString,time_t> > history;
LogWriter * obj;
public:
bool print;
Log(bool _print,QString _color,LogWriter *obj_ = NULL)
{print = _print; color = _color; obj = obj_;}
void setLock(QMutex *print_lock_){print_lock = print_lock_;}
void setTextField(QPlainTextEdit *_text) {text_place = _text;}
Log& operator<<(QString &a);
Log& operator<<(const char* a);
};
static LogWriter* getInstance()
{
static LogWriter instance; // Guaranteed to be destroyed.
// Instantiated on first use.
return &instance;
}
~LogWriter();
Log LOW,MEDIUM,HIGH;
Ui::LogWindow *ui;
signals:
void signalLogAppend(QString);
};
Упрощенный код определений методов:
LogWriter::LogWriter(QWidget * parent): QDialog(parent) {
ui = new Ui::LogWindow;
ui->setupUi(this);
LOW.setLock(&print_lock);
MEDIUM.setLock(&print_lock);
HIGH.setLock(&print_lock);
connect(this,SIGNAL(signalLogAppend(QString)),ui->plainTextEdit,
SLOT(appendHtml(QString)),Qt::DirectConnection);
}
LogWriter::Log& LogWriter::Log::operator<< (QString &s){
history.push_front(qMakePair(s,time(NULL)));
if(history.size() > MAX_SIZE) history.pop_back();
if(print){
//print_lock->lock();
QString text = "<font color=\"";
text += color + "\">";
text += s + "</font>";
//cout << text.toStdString() << endl;
//text_place->appendHtml(text);
//text_place->repaint();
emit (obj)->signalLogAppend(text);
//print_lock->unlock();
}
return *this;
}
У меня есть два отдельных файлов UI (первый для главного окна, второй для окна журнала). Я должен использовать окно журнала по всей моей программе (около 10 потоков), и я решил эту проблему. Мой вопрос: возможно ли принудительное обновление GUI без использования основного потока, а если нет - какие еще возможности у меня есть. Если возможно, я предпочел бы не восстанавливать весь мой код - мне понадобилось бы некоторое время, чтобы это сделать. Сейчас вход супер просто - я оны нужно:
LogWindow *log = LogWindow::getInstance();
log->MEDIUM << "something";
Как дополнительная информация добавить предупреждение QtCreator:
QObject::connect: Cannot queue arguments of type 'QTextBlock'
(Make sure 'QTextBlock' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
Да, я пытаюсь войти в фоновый поток (даже много потоков - с помощью оператора <<), но я не использую прямой вызов (или, может быть, я ошибаюсь), я использую сигнал для этого - так же, как в коде я прилагается. «Отправить сигнал через соединение по умолчанию» - что это значит? Кроме того, остальная часть этого предложения довольно размыта для меня. – lagoru
Что он имеет в виду в вашем соединении класса LogWritter, которое вы вызываете connect (....) с 5 аргументами. Удалите 5-й аргумент Qt: DirectConnection.Прямые соединения предназначены только для одних и тех же потоков. Либо удалите аргумент, и пусть Qt выяснит, что он должен быть Qt: QueuedConnection или просто упоминать его самостоятельно. Я считаю, что лучше быть явным в соединениях для сквозного сигнала-слота – Viv
OMG, он работает .... как я мог пропустить это, четыре дня поиска, в то время как я мог просто проверить, какие границы QT :: directconnection ... Спасибо очень за помощь !!! – lagoru