QTextEdit обновляется после setText () / insertPlainText () - PullRequest
1 голос
/ 15 июня 2019

У меня есть виджет QTextEdit в частном слоте, который я регулярно обновляю с помощью setText () и insertPlainText ().

Я обнаружил, что setText () / insertPlainText () не обновляет виджет QTextEdit немедленно. Вместо этого QTextWidget обновляется, когда возвращается функция слота. Чтобы проверить это, я поставил sleep () сразу после setText () / insertPlainText ().

class MyWindow : public Widget
{
    MyWindow()
    {
        my_button = new QPushButton(this);
        my_edit   = new QTextEdit(this);

        connect(my_button, 
                &QPushButton::clicked, 
                this, 
                &MyWindow::my_callback);
    }

    private slots:

        void my_callback()
        {
            my_edit->setText("sample text");

            // nothing happens; the QTextEdit 
            // widget does not show "sample text"

            sleep(10); 

            // the QTextEdit widget will show
            // "sample text" AFTER the sleep,
            // when my_callback returns.
         }

    private:
        QPushButton* my_button;
        QTextEdit*   my_edit;
}

Это проблема для меня, потому что мне нужно напечатать сообщение в моем виджете QTextEdit ПЕРЕД запуском трудоемкого процесса (используя QProcess). В настоящее время это сообщение не печатается до тех пор, пока не будет возвращен процесс QProcess.

Кто-нибудь знает, как можно заставить виджет QTextEdit отображать его содержимое сразу после setText () / insertPlainText ()?

Использование Qt5 в Fedora 29.

Ответы [ 2 ]

2 голосов
/ 15 июня 2019

Никогда не выполняйте задачу, которая занимает много времени в потоке GUI.В общем случае, решение состоит в том, чтобы выполнить эту задачу в другом потоке, но в вашем случае это указывает на то, что вы используете QProcess, поэтому я предполагаю, что вы используете один из методов waitForFinished (), waitForStarted () или waitForReadyRead (), вместо этого выследует использовать сигналы:

#include <QtWidgets>

class Widget: public QWidget{
    Q_OBJECT
public:
    Widget(QWidget *parent=nullptr):
        QWidget(parent)
    {
        button.setText("Press me");
        QVBoxLayout *lay = new QVBoxLayout{this};
        lay->addWidget(&button);
        lay->addWidget(&textedit);
        connect(&button, &QPushButton::clicked, this, &Widget::onClicked);
        connect(&process, &QProcess::readyReadStandardError, this, &Widget::onReadyReadStandardError);
        connect(&process, &QProcess::readyReadStandardOutput, this, &Widget::onReadAllStandardOutput);
    }
private Q_SLOTS:
    void onClicked(){
        textedit.setText("sample text");
        process.start("ping 8.8.8.8");
    }
    void onReadyReadStandardError(){
        textedit.append(process.readAllStandardError());
    }
    void onReadAllStandardOutput(){
        textedit.append(process.readAllStandardOutput());
    }
private:
    QPushButton button;
    QTextEdit textedit;
    QProcess process;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}
#include "main.moc"
0 голосов
/ 15 июня 2019

Интересно, если бы вызов

QCoreApplication::processEvents() 

сразу после -> setText ("образец текста") сработал бы в вашем случае.

...