上一篇https://blog.youkuaiyun.com/qq_23815725/article/details/104269587介绍了程序主要结构,之后几篇就开始写一些实现细节吧。
本文两个内容:按钮设置ID进行分组、按钮自锁。这里用上了C++的bitset库,这个真是太好用了,特别适合离散场景使用,可以把变量转换成2进制,也可以将2进制转换成byte或int一次性写入PLC。
一、按钮分组:
下图中圆点是按钮控件,用上了样式表,将按钮作为状态来显示故障。用按钮ID号来识别这些按钮,那样代码就非常简洁。
按钮分组步骤:
1.头文件:#include
2.声明:QButtonGroup *indexerrorLED;//分组故障指示灯
3.定义:
indexerrorLED=new QButtonGroup(this);
indexerrorLED->addButton(ui->Indicator_102,0);//线体有异常
indexerrorLED->addButton(ui->Indicator_103,1);//PLC通讯检测
indexerrorLED->addButton(ui->Indicator_xt01,8);//线头
indexerrorLED->addButton(ui->Indicator_xt02,9);
indexerrorLED->addButton(ui->Indicator_xt03,10);
indexerrorLED->addButton(ui->Indicator_xt04,11);
.....................
4.第3步做完后就可以用上for循环,根据ID号来识别按钮控件了。因为用上了样式表,两行代码有点长。
for(byte i=28;i<32;i++)//工位1
{
QPushButton* bbtn1=qobject_cast<QPushButton*>(indexerrorLED->button(i));
if(XT.test(i))
{
bbtn1->setStyleSheet("QPushButton{background-color:red;border-style:solid;border-width:1px;border-color:white;border-radius:12px;}");
}
if(!XT.test(i))
{
bbtn1->setStyleSheet("QPushButton{background-color:silver;border-style:solid;border-width:1px;border-color:white;border-radius:12px;}");
}
}
二、按钮自锁
如下图,是按钮自锁的效果:
按钮自锁是利用按钮分组来实现的:
这个仿真窗口是弹出式,不是堆栈式,需要新建一个ui,然后在这个ui程序中设置一个定时器,每1秒中读取这个ui的按钮状态,如果按钮本周期和上周期值不一样,就发送信号到主线程,主线程再写入PLC中(只写一次,然后等待下次按钮变化,节省系统开销)。
- 按钮click事件,这个实现按钮自锁效果,然后定时器读取这个按钮是否在isCheckable状态。其中背景色空着的就是默认颜色(应该是吧,我不知道背景色是多少,空着不写颜色的时候,发现和周围的按钮是一个颜色)。
if(ui->pushButton_GW1->isCheckable())
{
ui->pushButton_GW1->setCheckable(false);
ui->pushButton_GW1->setStyleSheet("QPushButton{background-color:;}");
}
else
{
ui->pushButton_GW1->setCheckable(true);
ui->pushButton_GW1->setStyleSheet("QPushButton{background-color:green;}");
}
- 周期读取,下面这个代码利用了bitset库,如果某个按钮是isCheckabel,就set相应位,然后发送给主线程,主线程再将这个状态打包(2进制转Int)发送给PLC,PLC相应变量就置位为1,代表复位按钮信号。
bitset<32> Sim(0);
for(int i=0;i<16;i++)
{
QPushButton* bbtn0=qobject_cast<QPushButton*>(SimButton->button(i));
if(bbtn0->isCheckable())
Sim.set(size_t(i));
else
Sim.reset(size_t(i));
}