项目结构如下:
device.h
#ifndef DEVICE_H
#define DEVICE_H
#include <QWidget>
class device : public QWidget
{
Q_OBJECT
signals:
void takeMidVal(int midVal);
public:
device(QWidget *parent = nullptr);
public slots:
void seek(int bin);
};
#endif // DEVICE_H
设备.cpp
#include "device.h"
device::device(QWidget *parent) :
QWidget(parent)
{
}
void device::seek(int bin)
{
int midVal = 800;
emit(takeMidVal(midVal));
}
对话框.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QApplication>
#include <QDialog>
#include <QPushButton>
#include <QVBoxLayout>
#include <math.h>
#include <windows.h>
#define ACCEPT_DIFF 100
#define SIZE_OF_SAMPLE 10
#define SIZE_OF_NOISE 10
#define MK_SILENCE -2
#define MK_INCORRECT_RESPONSE -1
#define MK_WAITING 0
#define MK_CORRECT_RESPONSE 1
class Dialog : public QDialog
{
Q_OBJECT
signals:
void sendCommand();
void setBinToSeek(int bin);
public:
int configRes;
int result;
int midCount;
int midValue;
bool waitFlag;
QPushButton* btn;
explicit Dialog(QWidget *parent = nullptr);
~Dialog();
public slots:
void computeMid(int curVal);
private slots:
void handleClick();
};
#endif // DIALOG_H
对话框.cpp
#include "dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent)
{
QVBoxLayout *mainLayout = new QVBoxLayout;
btn = new QPushButton();
mainLayout->addWidget(btn);
this->setLayout(mainLayout);
connect(btn,SIGNAL(clicked()),this,SLOT(handleClick()));
}
void Dialog::handleClick()
{
result = -1;
int amplitude = 1000;
int bin = 10;
unsigned char min = 1;
unsigned char max =static_cast<unsigned char>(255);
unsigned char command = 0;
bool success = false;
while(max-min > 1)
{
command = (min + (max-min)/2);
configRes = MK_WAITING;
emit(sendCommand());
while(configRes == MK_WAITING)
{
QApplication::instance()->processEvents();
Sleep(100);
}
emit(setBinToSeek(bin));
waitFlag = true;
midCount = 0;
midValue = 0;
int sleepCount = 0;
while(waitFlag)
{
if(sleepCount >= 50)
{
return;
}
QApplication::instance()->processEvents();
Sleep(300); //wait untill get mid value of pick in other thread
++sleepCount;
}
int diff = amplitude - midValue;
if(diff < 0)
{
if(-diff < ACCEPT_DIFF)
{
success = true;
break;
}
else
{
min = static_cast<unsigned char>(command);
}
}
else
{
if(diff < ACCEPT_DIFF)
{
success = true;
break;
}
else
{
max = static_cast<unsigned char>(command);
}
}
}
if(success)
{
result = static_cast<int>(command);
return;
}
}
void Dialog::computeMid(int curVal)
{
midValue += curVal;
++midCount;
if(midCount >= SIZE_OF_SAMPLE)
{
midValue /= midCount;
waitFlag = false;
}
}
Dialog::~Dialog()
{
}
主窗口.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTimer>
#include "dialog.h"
#include "device.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
QPushButton* btn;
QTimer timer;
Dialog* d;
device* dev;
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void createDialog();
void handleTimeOut();
void sendCommand();
};
#endif // MAINWINDOW_H
主窗口.cpp:
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
dev = new device(this);
btn = new QPushButton();
this->layout()->addWidget(btn);
connect(btn,SIGNAL(clicked()),this,SLOT(createDialog()));
connect(&timer,SIGNAL(timeout()),this,SLOT(handleTimeOut()));
}
void MainWindow::sendCommand()
{
timer.start(5000);
}
void MainWindow::createDialog()
{
d = new Dialog();
connect(d,SIGNAL(sendCommand()),this,SLOT(sendCommand()));
connect(dev,SIGNAL(takeMidVal(int)),d,SLOT(computeMid(int)));
connect(d,SIGNAL(setBinToSeek(int)),dev,SLOT(seek(int)));
d->exec();
}
void MainWindow::handleTimeOut()
{
d->configRes = MK_CORRECT_RESPONSE;
}
MainWindow::~MainWindow()
{
}
主文件
#include <QApplication>
#include <QtCore>
#include <QtGui>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
示例项目本身
当我发送信号时,调用了 sendCommand 插槽,这没有问题。但是从槽返回后,当定时器到期时,处理程序不会被调用。计时器完成后如何跳转到处理程序?
如果我们从一个抽象的例子转移到一个真实的例子,那么会发生以下情况:从主窗口调用一个模式。在模态窗口执行代码期间,会向主机发送信号,以通过 COM 端口向设备发送命令。此外,有必要从设备接收响应并处理它的缺失或不正确。为此,使用了计时器。
据我了解,发出信号后,模态窗口代码的执行一刻也没有停过,于是我就把它无限循环,直到flag落下,表示所有处理完成。
但问题是定时器并没有以任何方式触发handler调用,退出slot后什么也没有发生,模态窗口代码的执行就陷入了死循环。
已添加以下内容。通过调用handleClick,生成一个命令,发送到device1,影响device2的输出。之后,向 device2 发送一个信号,以便它开始返回某个值。当收集到足够数量的这些值时,会计算它们的算术平均值,并估计接收到的值与期望值之间的差异。如果差值大于最小值,则球队的阵型会有调整,一切都重新开始。
你当然可以关注
但是,一般来说,应该删除这个循环,根本不需要它。据我了解,某处的 com 端口应该有一些东西,所以如果答案来了,发出一个确认已经到来的信号,如果没有,则触发响应等待计时器,表明什么都没有到来。在这两种情况下,都会发生某些事情并且直接关闭(或不关闭)对话框,也就是说,以通常的方式,而不是通过标志。
例如,您需要在对话框中告知信号已超时。我们这样做:
如果我们收到来自 com 端口的响应,那么我们只是停止计时器并且不接收任何文件。