0

私は最近 QThreads API を使い始めたばかりで、奇妙な問題に直面しました。

run() メソッドを再実装した QThread のサブクラスを作成しました。

void ThreadChecker::run()
{
    emit TotalDbSize(1000);

    for (int i = 0; i < 1000; i++)
    {
        QString number;
        number.setNum(i);
        number.append("\n");
        emit SimpleMessage(number);
        //pausing is necessary, since in the real program the thread will perform quite lenghty tasks
        usleep(10000);
    }
}

このスレッドを呼び出すコードは次のとおりです。

ThreadChecker thread;


connect(&thread, SIGNAL(TotalDbSize(int)), this, SLOT(SetMaximumProgress(int)));
//This slot writes the message into the QTextEdit
connect(&thread, SIGNAL(SimpleMessage(QString)), this, SLOT(ProcessSimpleMessage(QString)));

thread.start();

私がこれを機能させる方法は、QTextEdit が 10 ミリ秒ごとに更新されるようにすることです。しかし、代わりに、プログラムは 10 秒間遅れるだけで、すべての信号が一度に急増します。さらに、プログラムが遅れている間、イベントループがブロックされているように動作します(ボタンが押されない、サイズ変更が機能しないなど)

ここで何が欠けていますか?

4

1 に答える 1

1

次のコードを試してください。

class Updater: public QObject
{
    Q_OBJECT
public slots:
    void updateLoop()
    {
        emit TotalDbSize(1000);

        for (int i = 0; i < 1000; i++)
        {
            QString number;
            number.setNum(i);
            number.append("\n");
            emit SimpleMessage(number);
            //pausing is necessary, since in the real program the thread will perform quite lenghty tasks
            usleep(10000);
        }
    }
signals:
    void TotalDbSize(...);
    void SimpleMessage(...);

};
...
QThread updaterThread;
Updater updater;
updater.moveToThread(&updaterThread);
connect(&updater, SIGNAL(TotalDbSize(int)), this, SLOT(SetMaximumProgress(int)));
//This slot writes the message into the QTextEdit
connect(&updater, SIGNAL(SimpleMessage(QString)), this, SLOT(ProcessSimpleMessage(QString)));
connect(&updaterThread, SIGNAL(started()), &updater, SLOT(updateLoop()));
updaterThread.start();

チェックはしていませんが。updaterThreadそれを保証し、範囲外にupdaterならないようにする必要があることに注意してください。

======

質問のコードが機能しないのはなぜですか? 私が推測できるのは、シグナルが QThread オブジェクトにアタッチされていることと、同じスレッドにあるため、connect直接接続されていることです。そのため、シグナルの直接接続が機能し、TextBox を GUI スレッドの外部から更新すると、間違った結果が生じる可能性があります。ただし、私の推測は間違っている可能性があり、デバッガーで正確な原因を見つけることができることに注意してください。threadthis

スレッド、イベント、QObjects の記事もお読みください。Qtでのスレッドの正しい使い方がよくわかる記事です。

于 2013-11-07T08:22:43.483 に答える