0

「n」回連続して「一部のテキスト」を QTextBrowser に出力しようとしています。「n」は整数です。このために、タイミングのために QTimer::SingleShot を使用しました。タイムアウトがトリガーされると、FLAG が false に設定され、この「FLAG」が while ループで監視され、FLAG が false の場合に中断され、FLAG が FALSE に設定されるまでテキストが挿入されます。FLAG の初期値は true です。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QThread>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    FLAG = true;

}

void MainWindow::on_pushButton_clicked()
{
    ui->pushButton->setEnabled(false);
   RunTheTimer();
    int counter = 0;

    do
    {
        ui->textBrowser->insertPlainText(QString("Inside While loop %1 \n").arg(counter++));
        counter++;
    }while(FLAG);

    FLAG = true;

}
void MainWindow::RunTheTimer()
{
     ui->textBrowser-> insertPlainText("Timer Started");
    QTimer::singleShot(60000, this, SLOT(Update()));// One Minute

}

void MainWindow::Update()
{
   ui->textBrowser-> insertPlainText("Timeout signal triggered");
    ui->pushButton->setEnabled(true);
   FLAG = false;
}
MainWindow::~MainWindow()
{
    delete ui;
}

プッシュボタンをクリックすると、アプリケーションがハングします。デバッグ後、実行が while(1) ループに入るとタイムアウトがトリガーされず、アプリケーションは while(1) ループ内にテキストを挿入できません。なぜこの動作ですか?私は何を間違っていますか?

ありがとう。

4

1 に答える 1

5

イベント ループに制御を戻していません。Qt の多くのことは、イベント ループなしでは機能しないように設計されています。あなたの場合、Qt wiki のこのページを見てください。

  • QTextBrowser新しく追加されたテキストを表示することはできません。これは、ウィジェットがペイント イベントを受信できる必要があるためです (これはイベント ループなしでは不可能です)。
  • フラグを false に設定するタイマーは起動できません。これは、プログラムが常にwhileループの実行でビジーであり、他に何もできないためです (そのwhileループから抜け出して、次の場合にこれが不可能でない限り) 。フラグを false に設定しません. . .)。

無限ループを使用する代わりに、何かをできるだけ繰り返し実行したい場合は、a を使用してintervalQTimerプロパティを 0 に設定できます。これは、イベント ループがすべての処理を終了するとすぐにタイマーをタイムアウトさせる特別な値です。イベント キュー内のイベント。

無限ループの代わりに上記のアプローチを使用すると、別のタイマーを使用して、特定の時間後に上記のタイマーを停止できます。イベント ループは常に実行されているため、イベントが到着せず、タイマーが起動しないことを心配する必要はありません。今。

上記のアプローチの可能な実装を次に示します。

スクリーンショット

#include <QtWidgets>

int main(int argc, char* argv[]){
    QApplication a(argc, argv);

    //set up GUI
    QWidget widget;
    QVBoxLayout layout(&widget);
    QTextBrowser textBrowser;
    QPushButton button("Add Text");
    layout.addWidget(&textBrowser);
    layout.addWidget(&button);

    //timer with 0 interval instead of while loop
    QTimer workTimer;
    workTimer.setInterval(0);
    int counter=0;
    QObject::connect(&workTimer, &QTimer::timeout, [&]{
        //add text to textBrowser whenever the workTimer fires
        textBrowser.append(QStringLiteral("Additional Text %1").arg(counter++));
    });
    //when the button is clicked
    QObject::connect(&button, &QPushButton::clicked, [&]{
        //start work timer
        workTimer.start();
        button.setEnabled(false);
        //stop work timer after 5 seconds
        QTimer::singleShot(5000, [&]{
            workTimer.stop();
            button.setEnabled(true);
        });
    });
    widget.show();

    return a.exec();
}
于 2016-12-17T11:49:08.287 に答える