现在在用Qt做一个智能家居的项目,解决了一个问题,拿出来分享一下:
为了描述简单,按钮用DirectButton来表示,窗体用Form来表示。
介绍:一个窗体代表一个家电(如压力锅),在窗体上有一些按钮,如开关,煮饭,煮粥之类的,让开关按钮能够控制其他按钮,即只有电器是开的时候其他按钮才能按下。因为DirectButton与DirectButton是独立不相关的,因此,通过窗体这个共同体的变量来控制。
问题:DirectButton类和Form 类是两个独立的类,对象之间不能互相访问对象的成员。
方法:通过建立一个监听类来解决,这个类如下:
IPowerInfoListener.h
#ifndef IPOWERINFOLISTENER_H #define IPOWERINFOLISTENER_H class IPowerInfoListener { public: virtual bool isOn() = 0; }; #endif // IPOWERINFOLISTENER_H
IPowerControlListener.h
#ifndef IPOWERCONTROLLISTENER_H #define IPOWERCONTROLLISTENER_H #include"IPowerInfoListener.h" class IPowerControlListener : public IPowerInfoListener { public: virtual void power_on() = 0; virtual void power_off() = 0; }; #endif // IPOWERCONTROLLISTENER_H
然后,让Button有一个IPowerControlListener类的数据成员,代码如下:
button.h
#ifndef BUTTON_H #define BUTTON_H #include <QtGui/QPushButton> #include<command.h> #include"IPowerControlListener.h" class Q_GUI_EXPORT Button : public QPushButton { Q_OBJECT public: Button(Command command, IPowerControlListener *powerListener = 0); IPowerControlListener *listner; }; #endif // BUTTON_H
button.cpp
Button::Button(Command command, IPowerControlListener *powerListener) { this->listner = powerListener; }
再继承Button类:
class Q_GUI_EXPORT DirectButton : public Button { Q_OBJECT public: DirectButton(QWidget *parent = 0); DirectButton(int loc_id, QWidget *parent = 0); DirectButton(QString desc, QWidget *parent = 0); DirectButton(Command command, IPowerControlListener *listener = 0); ~DirectButton(){} bool execute(); protected: int parseInstrument(); //int mode_id; };
bool DirectButton::execute() { unsigned char a[4]; bool ok = false; //the instrucments need to transfer. a[0] = (unsigned char)this->command().op_mac.toInt(&ok, 16); a[1] = (unsigned char)this->command().op_type.toInt(&ok, 16); a[2] = (unsigned char)this->command().op_code.toInt(&ok, 16); a[3] = (unsigned char)this->command().op_num.toInt(&ok, 16); //find the SPI char *str[] = {"/dev/ttyS0", "/dev/ttyS1", "/dev/ttyS2", "/dev/ttyS3"}; int i = this->command().spi; this->SendCommand(a, str[i]); return true; }
同理,让窗体继承类IPowerControlListener
代码如下:
form.h
class Appliance : public QWidget, public IPowerControlListener { Q_OBJECT public: Appliance(QString strMac,QString strType, int intSpi, QWidget *parent = 0); ~Appliance(); void Init(QString strMac,QString strType, int intSpi); void power_on();//open void power_off();//off bool isOn();//the status }
这样子以来,DirectButton在界面生成时,Form被作为参数传入了DirectButton中,成为了DirectButton的一个数据成员。
我们可以通过:
this->listner->power_on(); this->listner->power_off();
这两个函数来修改this.listner->isOn()
在Form中,我们在通过
DirectButton* btn = qobject_cast<DirectButton*>(sender());
if(btn->listner->isOn())
btn->execute();
来判断电器是否处于开的状态来控制