Home > Enterprise >  QT Multithread GUI, allowing to update more elements simultaneously
QT Multithread GUI, allowing to update more elements simultaneously

Time:02-23

My program has 3x tabs with different functions and I noticed today this issue: when starting the function in third tab which is running in separate thread but updating QPlainText widget on this tab (sometimes once a few seconds, sometimes every update is under one second and takes e.g. minute, let's say like loading progress bar) I can't use functions and widgets on another tabs, especially when I have to enter some text to lineEdit widget before I click on starting button- it's impossible as I'm immediately out from the lineEdit (or I have to click with the mouse on it and enter one char real fast). I know from the QT tutorials and other sites that GUI is running in one main thread, but I'm wondering how large projects like KDE for Linux is written if that was the real issue. How to make it not blocking?

//EDIT So I'm using QTabWidget but it doesn't matter, on Tab3 I'm starting new thread which makes some API requests and calculations, then emit signals to update QPlainTextEdit:

void QtWidgetsApplication1::on_pushButton_2_clicked() {

    mThread = new QThread;
    worker = new BinconThreadWorker;
    worker->Stop = false;
    QObject::connect(mThread, SIGNAL(started()), worker, SLOT(process()));
    QObject::connect(worker, SIGNAL(valueChanged(std::string)), this, SLOT(onValueChanged(std::string)));
    QObject::connect(worker, SIGNAL(valueSecChanged(std::string)), this, SLOT(onValueSecChanged(std::string)));
    QObject::connect(worker, SIGNAL(finished()), mThread, SLOT(quit()));
    QObject::connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    QObject::connect(mThread, SIGNAL(finished()), mThread, SLOT(deleteLater()));
    worker->moveToThread(mThread);
    mThread->start();

}

void QtWidgetsApplication1::onValueChanged(std::string s) {

    ui.plainTextEdit->appendPlainText(QString::fromStdString(s));
    ui.plainTextEdit->verticalScrollBar()->setValue(maximumHeight());
}

void QtWidgetsApplication1::onValueSecChanged(std::string s) {

    ui.plainTextEdit->setFocus();
    QTextCursor storeCursorPos = ui.plainTextEdit->textCursor();
    ui.plainTextEdit->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
    ui.plainTextEdit->moveCursor(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
    ui.plainTextEdit->moveCursor(QTextCursor::End, QTextCursor::KeepAnchor);
    ui.plainTextEdit->textCursor().removeSelectedText();
    ui.plainTextEdit->textCursor().deletePreviousChar();
    ui.plainTextEdit->setTextCursor(storeCursorPos);

    ui.plainTextEdit->appendPlainText(QString::fromStdString(s));
    ui.plainTextEdit->verticalScrollBar()->setValue(maximumHeight());
}

In the same time I want to do other things on Tab2 where is QLineEdit widget and button which does something on this tab, but when I click on QLineEdit widget the cursor disappears so I can't enter any text because QPlainTextEdit on Tab3 is getting signals so it updates it's content and it deactivates QLineEdit on the other tab when I'm trying to use it. It happenes only if it comes to the situation when QPlainTextEdit is updated in short intervals of time, under 1s.

CodePudding user response:

The problem is simply the statement...

ui.plainTextEdit->setFocus();

in QtWidgetsApplication1::onValueSecChanged. It 'steals' the input focus from the current focus holder -- the QLineEdit in your case. Just remove that line and things should work as expected.

  • Related