11

Qt SDKの例に従って、QThreadサブクラスでタイマーを開始しますが、警告が表示され続け、スレッドがタイマーを開始することはありません。コードは次のとおりです。

NotificationThread::NotificationThread(QObject *parent)
           :QThread(parent),
           m_timerInterval(0)
{
 moveToThread(this);
}


NotificationThread::~NotificationThread()
{
 ;
}

void NotificationThread::fire()
{
  WRITELOG("A::fire called -- currentThread:" + QString::number((int)currentThread()->currentThreadId()));
  QVector<StringPer>* batchVectorResult = new QVector<StringPer>();   
  emit UpdateGroupNotifications(batchVectorResult);

}

void NotificationThread::run()
{

      connect(&m_NotificationTimer, SIGNAL(timeout()),
              this,SLOT(fire(),Qt::DirectConnection));

      WRITELOG("A::run() worker thread -- currentThread:" + QString::number((int)currentThread()->currentThreadId()));
   //SetNotificationTimerFromConf();
   QVariant val(ConfigSettings::getInstance()->ReadFromSettingsReturnVariant(SETTINGS_KEY_NOTIFICATIONTHREAD));
   int interval = val.toInt();
   m_NotificationTimer.setInterval(interval);
      m_NotificationTimer.start();

      QThread::exec();
}


void NotificationThread::SetNotificationTimerFromConf()
{
 QVariant val(ConfigSettings::getInstance()->ReadFromSettingsReturnVariant(SETTINGS_KEY_NOTIFICATIONTHREAD));
 int interval = val.toInt();
 m_NotificationTimer.setInterval(interval);
}


void NotificationThread::UpdateNotificationTimerRT(int timerInterval)
{
 m_NotificationTimer.setInterval(m_timerInterval);
}


void NotificationThread::Execute(const QStringList batchReqList)
{
 QVector<QString>* batchVectorResult = new QVector<QString>();   
 start();
}

メインGUIからスレッドを開始しExecute( )ます。

4

3 に答える 3

14

問題は、スレッドオブジェクトを作成するときに、メインスレッドによって暗黙的にタイマーを作成することです。これは、タイマーがスレッドクラスのメンバーであるためです。

run()タイマーを開始しようとすると、タイマーが作成されたスレッドではなく、別のスレッド(in )で実行します。これにより、警告が表示されます。

実行するスレッドにタイマーを作成する必要があります。クラス内のの宣言をから変更m_notificationTimerしますNotificcationThread

QTimer m_NotificationTimer;

QTimer* m_NotificationTimer;

でタイマーを作成しrun()ます

m_NotificationTimer = new QTimer(this);
m_NotificationTimer->setInterval(interval);
m_NotificationTimer->start();
于 2011-06-06T13:05:15.190 に答える
8

行を追加する場合

m_NotificationTimer.moveToThread(this);

タイマーオブジェクトのそのポイントからスレッドのrun()メソッドの開始まで、スレッド内の接続されたスロットを呼び出します。

タイマーを最初に作成すると、メインスレッド内で実行されます。上記のように独自のスレッドに移動すると、moveToThreadメソッドはタイマーオブジェクトのスレッドアフィニティを変更します。

于 2011-06-06T14:41:21.410 に答える
4

この記事にも言及する価値があります

私にとって最大の調整は、qtのスレッドがインターフェースとして使用され、実際にはサブクラス化を目的としていないことを理解することでした。そうは言っても、私はあなたのクラスと実際のQThreadを別々に保ちます。次に、YourClass.moveToThread(&YourQtThread)を使用して、シグナルとスロットがそのスレッドで処理されるようにします。

于 2011-12-09T16:18:04.100 に答える