0

ロボットのセンサー用のいくつかのプロジェクト用に、独自の QTimer と QThread を持つクラスを作成したいと思います。色々検索したらこんなの出てきた

#include <QCoreApplication>
#include <QTimer>
#include <QThread>
#include <QObject>
#include <QDebug>


//#####################( Robot Class  )#########################3

class Robot : public QObject
{
public:
    Robot(QObject *parent = 0);
    ~Robot();

private:
    QTimer  *mQTimer;
    QThread *mQThread;

public slots:
    void update();

};

Robot::Robot(QObject *parent)
    : QObject(parent)
{
     mQTimer = new QTimer(0);
    mQThread = new QThread(this);

    mQTimer->setInterval(1);
    mQTimer->moveToThread(mQThread);

    connect(mQTimer, SIGNAL(timeout()), this, SLOT(update()));
    connect(mQThread, SIGNAL(started()), mQTimer, SLOT(start()));

   mQThread->start();
   //mQTimer->start();

}

Robot::~Robot()
{
    delete mQTimer;
    delete mQThread;
}

void Robot::update()
{
    qDebug() << "Robot is updating ...";
}

//##################( Main )###########################
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Robot *myRobot = new Robot(0);

    return a.exec();
}

このエラーが発生しています

QObject::connect: No such slot QObject::update() in ..\untitled1\main.cpp:34
QObject::connect: No such slot QObject::update() in ..\untitled1\main.cpp:34
4

2 に答える 2

3

クラスに Q_OBJECT マクロがありません。また、Qt メソッド名と混在させることができるため、そのようなメソッドの命名は避けてください。また、この場合、作成するクラスごとに追加のヘッダーと cpp ファイルを作成し、robtot.h と robot.cpp を作成します。

class Robot : public QObject
{
Q_OBJECT
public:
    Robot(QObject *parent = 0);
    ~Robot();
...
于 2015-07-20T15:11:53.960 に答える
1

以下は私のために働きます。マクロを忘れてQ_OBJECT、 の静的メタデータを定義する moc 出力を含めましたRobot

Robot::updateもちろん、スロットはメイン スレッドで実行されるため、このコードに意味はありません。

コードには 2 つのスレッドがあります。Robotオブジェクトが存在するメイン スレッドとrobot.mThread、タイマーが存在する です。タイマーは でタイムアウトになりmThread、メイン スレッドでスロット呼び出しをキューに入れます。そのスロット呼び出しは、スタック上で呼び出すことrobot.updateになります。a.exec

を使用してヒープに割り当てられたタイマーとスレッドを明示的に持つ必要がないことに注意してくださいnewRobotそれらは、またはその PIMPL の直接のメンバーである必要があります。

main.cpp

#include <QCoreApplication>
#include <QTimer>
#include <QThread>
#include <QDebug>

class Robot : public QObject
{
   Q_OBJECT
   QTimer mTimer;
   QThread mThread;
public:
   Robot(QObject *parent = 0) : QObject(parent) {
      connect(&mTimer, &QTimer::timeout, this, &Robot::update);;
      mTimer.start(1000);
      mTimer.moveToThread(&mThread);
      mThread.start();
   }
   Q_SLOT void update() {
      qDebug() << "updating";
   }
};

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   Robot robot;
   return a.exec();
}

#include "main.moc"

ロボット全体を独自のスレッドに移動する方が理にかなっています。その場合、ロボットが所有するすべてのオブジェクトに親子関係を設定する必要があることに注意してください。これにより、Robotオブジェクトとともにスレッドがすべて切り替わります。

このThreadクラスは、長年にわたる使いやすさのバグを修正し、QThreadいつでも安全に破棄できる真の RAII クラスに変換します。

main.cpp

#include <QCoreApplication>
#include <QTimer>
#include <QThread>
#include <QDebug>

class Thread : public QThread {
   using QThread::run;
public:
   ~Thread() { quit(); wait(); }
};

class Robot : public QObject
{
   Q_OBJECT
   QTimer mTimer;
   int mCounter;
public:
   Robot(QObject *parent = 0) : QObject(parent), mTimer(this), mCounter(0) {
      connect(&mTimer, &QTimer::timeout, this, &Robot::update);;
      mTimer.start(1000);
   }
   Q_SLOT void update() {
      qDebug() << "updating";
      if (++mCounter > 5) qApp->exit();
   }
};

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   Robot robot;
   Thread thread;
   robot.moveToThread(&thread);
   thread.start();
   return a.exec();
}

#include "main.moc"
于 2015-07-20T16:25:52.080 に答える