我從上週開始因QPlainTextEdit更新而引發問題。我試圖用QPlainTextEdit從QMainWindow對話窗口中單獨創建。當我嘗試使用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;
}
我有兩個獨立的用戶界面的文件(第一對主窗口中,第二日誌窗口)。 我必須在我的程序中使用日誌窗口(約10個線程),並且我對此問題進行了處理。我的問題是 - 是否有可能在不使用主線程的情況下強制GUI更新,如果沒有 - 我還有其他可能性。如果可能的話,我寧願避免重新構建我的所有代碼 - 這需要我一些時間來完成。現在登錄是超級容易 - 我ONY需要:
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 2013-03-05 19:47:09
他的意思是在你使用5個參數調用connect(....)的LogWritter類連接中。刪除第五個參數Qt:DirectConnection。直接連接僅適用於相同的線程連接。要麼刪除參數並讓Qt知道它需要是Qt:QueuedConnection,或者只是自己提及它。我發現最好是明確的交叉線程信號插槽 – Viv 2013-03-05 20:23:37
OMG它的工作....我怎麼會錯過,四天的搜索,而我可以檢查什麼QT ::直接連接邊界是...謝謝非常多的幫助! – lagoru 2013-03-05 21:25:32