实现QTimer以在给定时间内执行函数

时间:2016-03-11 05:47:45

标签: c++ qt

我有一个函数应该根据参数将数据发送到覆盆子pi给定的时间段。

//headerfiles
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
Ui::MainWindow *ui;
 QUdpSocket udpSocket;
 // movement Timer
 QTimer* movementTimer;

private slots:
        void sendDatagram(); // Sends to the RaspberryPi
        void processFrameAndUpdateGUI();
        void turnLeft(double time);
        void turnRight(double time);
        void goStraight(double time);
        void MovRobot();

};

// MainWindow.cpp

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        movementTimer = new QTimer(this);
    //send datagram sends data to tehe PI.
        connect(movementTimer, SIGNAL(timeout()), this, SLOT(sendDatagram()));
       MovRobot(); // MovRobot() function 
    }

   // controls robot to turn left for specified time 

    void TurnLeft(double time)
    {
       s = 1; // sets the value to be sent to the PI.
        movementTimer->setInterval(time);
        movementTimer->setSingleShot(true);
        movementTimer->start();

    } 

//sendDatagram() slot
void MainWindow::sendDatagram() {

    QString datagramOutput = "start," + 
    QString::number(w) + ',' + QString::number(a) + ',' +
    QString::number(s) + ',' + QString::number(d) + ',' +
    QString::number(ui->motorSpeedSlider->value()) + ',' +
    QString::number(dispenserSignal);   
    datagramOutput += ",end";


    QByteArray datagram;
    QDataStream out(&datagram,QIODevice::WriteOnly);
    out << datagramOutput;
    udpSocket.writeDatagram(datagram,QHostAddress("192.168.0.104"),12345);   
}

//MovRobot  Function;

void MainWindow :: MovRobot() {
if (ui->pushButton_3->isChecked()) {

    MapArea(); // This function maps the area....
    // final_plan is a vector<Point2i> that stores positions on the map for  
    // the robot to move to 

    for (int i = 0; i < final_plan.size(); i++) {

        for (int j = final_plan.size() - 1; j>=0;  j--) {

            do {
                Mat src;
                bool bsuccess = cap.read(src);

                if (!bsuccess) {

                    ui->label_34->setText("Status: Can't read frame.");
                    ui->pushButton_3->setChecked(0);
                }

                GetRobotPosition(src);
                // AngleToGoal calculates the angle of the robot relative 
                // to the final goal.
                double tempAngle = AngletoGoal(final_plan[i][j]);

                if (tempAngle>=0) {
                    turnLeft(TimeToTurn(tempAngle));
                }
                else {
                    turnRight(TimeToTurn(tempAngle));
                }

                double tempDistance = DistancetoGoal(final_plan[i][j]);

                goStraight(tempDistance);

            } while (DistancetoGoal(final_plan[i][j])<20);

        }

    }


}

}

定时器只应将数据发送到PI,持续时间time sendDatagram是将数据发送到Pi的函数。这里有什么我想念的吗?计时器不会在TurnLeft()功能内启动,也不会运行。我是不是错了?

编辑:2016年3月13日:

我对迟到的回复表示歉意。这几天我病得很重。我添加了代码的相关部分。 MovRobot()是负责移动的主要函数,在MainWindow的构造函数中调用它。我已调试并逐步执行该程序,是的,TurnLeft()被调用。但是,sendDatagram()槽实际上并没有在函数中发送任何内容。为了确认sendDatagram()实际上有效,我使用另一个计时器连续向机器人上的PI发送信息以控制手臂。

// Header File
    QTimer* tmrTimer;

   private slot:
    void processFrameAndUpdateGUI();

// MainWindow Constructor:
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
      connect(tmrTimer, SIGNAL(timeout()), this, SLOT(processFrameAndUpdateGUI()));
        tmrTimer->start(10);
}

void MainWindow::processFrameAndUpdateGUI() {

 sendDatagram();

   }

sendDatagram()广告位几乎相同,只是我更改了发送给PI的值,这看起来效果很好。

然而,我最初的问题是,我想将数据发送到机器人,其中指定的时间,因为这会使机器人转动x度。这就是为什么我做了movementTimer()单发。 单步执行我的程序,我知道在我的TurnLeft函数中调用了这一行。

movementTimer->start();

sendDatagram()广告位本身实际上并未向PI发送任何内容。

2 个答案:

答案 0 :(得分:0)

根据您的代码。该程序从未调用过TurnLeft()。所以计时器从未开始。最好在constrator中启动计时器。

答案 1 :(得分:0)

timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(MySlot()));
timer->start(1000);

我会尝试将计时器设置为在构造函数中启动。