지난 주부터 QPlainTextEdit의 업데이트로 인한 문제가 발생했습니다. 내부 QPlainTextEdit QMainWindow 대화 창에서 별도로 만들려고 해요. 문제는 appendHtml 신호 (appendText로 시도 함)를 사용하려고 할 때 시작됩니다. 배치 된 텍스트는 마우스로 표시하지 않는 한 보이지 않습니다. 프로그램이 충돌하거나 보이는 조치가 없으면 원인을 다시 채우거나 업데이트하십시오. QPlainTextEdit 헤더와 인 QDialog의Qt가 메인 스레드가 아닌 GUI를 강제 업데이트하는 방법
단순화 번호 : 메소드 정의
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;
}
I는 (제 로그 윈도우에 대한 제 1 주 윈도우의) 두 개의 분리 된 인터페이스 파일을 갖는다. 내 프로그램 전체에서 로그 창을 사용해야하는데 (약 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
그가 의미하는 것은 5 개의 인수로 connect (....)를 호출하는 LogWritter 클래스 연결에있다.다섯 번째 인수 인 Qt : DirectConnection을 제거합니다. 직접 연결은 동일한 스레드 연결에만 적용됩니다. 인수를 제거하고 Qt가 QueuedConnection 일 필요가 있음을 Qt가 알게하거나 그냥 직접 언급하십시오. 내가 크로스 스레드 신호 슬롯에 대한 연결에 명시하는 것이 더 좋은 것을 발견 – Viv
OMG 작동합니다 .... 내가 어떻게 QT를 확인할 수있는 동안 4 일간의 검색을 놓칠 수 : : 직접 연결 경계는 ... 감사합니다 Logged 대단히 도움을! – lagoru