我这里主要讲的是嵌入式linux qt,目前,嵌入式当中,完美而且稳定的qt当属qt 2.3(一般简称qt 2.x),而且,高版本的qt都很难移植到linux当中,一方面是不稳定,另一方面是移植起来相当的麻烦。Qt 4到现在为止,还没有看到有人移植成功。
那么,嵌入式linux qt中(以下简称Qt),有两种方法可以达到点击按钮切换局部界面的目的。
第一种,使用QTabDialog,使用QTabDialog的效果如下图:
这种使用已经封装好了的类来实现,比较直观,也比较简单,我在这里就不赘述了。
可能QTabDialog还不能满足我们的需要,我这里重点讲述第二种方法。
第二种方法:使用QWidgetStack类来实现。
我的演示程序界面图如下:
以这个界面为例子。我们希望自己的界面程序,通过点击 左边的按钮:启动,设置,网络,停止,推出,右边的空白区域从而切换到相应的界面去。关于本实例的布局简单的说下:最底层是一个QWidget,然后使用了QGridLayout。右边的空白区域使用了gridLayout->addMultiCellWidget(),来实现合并Grid的目的。
主要实现的思想是:各个按钮都对应了各自的一个QWidget,然后在最底层实现connect()来连接信号与插槽。
首先,看下头文件:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "setWidget.h"
#include "netWget.h"
classSystemMain :publicQWidget
{
Q_OBJECT
public:
SystemMain(QWidget *parent = 0,char*name = 0);
publicslots:
voidstartAct();
voidsetAct();
voidnetAct();
voidstopAct();
signals:
//...
private:
QGridLayout *griLayout;//底层布局
QWidget *startWget;//启动按钮对应的切换界面
QWidget *netWget;//网络按钮对应的切换界面
QWidget *stopWget;//停止按钮对应的切换界面
SetWgetPan *setWget;//设置按钮对应的切换界面
QWidgetStack *dispArea;/*这个地方是整个局部界面切换的核心,定义一个QWidget的栈,栈顾名思义,就是就是堆叠起来,多个QWidget堆叠起来*/
//即将使用的button按钮
QPushButton *startButton, *setButton, *netButton, *stopButton, *exitButton;
};
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "setWidget.h"
#include "netWget.h"
class SystemMain : public QWidget
{
Q_OBJECT
public:
SystemMain(QWidget *parent = 0, char *name = 0);
public slots:
void startAct();
void setAct();
void netAct();
void stopAct();
signals:
//...
private:
QGridLayout *griLayout; //底层布局
QWidget *startWget; //启动按钮对应的切换界面
QWidget *netWget;//网络按钮对应的切换界面
QWidget *stopWget;//停止按钮对应的切换界面
SetWgetPan *setWget;//设置按钮对应的切换界面
QWidgetStack *dispArea; /*这个地方是整个局部界面切换的核心,定义一个QWidget的栈,栈顾名思义,就是就是堆叠起来,多个QWidget堆叠起来*/
//即将使用的button按钮
QPushButton *startButton, *setButton, *netButton, *stopButton, *exitButton;
};
这里的核心部分就是定义了也给 QWidgetStack 的对象,这里,之所以会在底层QWidget头文件中定义这些按钮和相应的QWidget,就是为了实现按钮和QWidget信号插槽的连接。
更具qt 2.3的 manpage中对QWidgetStack介绍如下:
The QWidgetStack class provides a stack of widgets, where the user can see only the top widget.
The application programmer can move any widget to the top of the stack at any time using the slot raiseWidget(), and add or remove widgets using addWidget() and removeWidget().
visibleWidget() is the get equivalent of raiseWidget(); it returns a pointer to the widget that is currently on the top of the stack.
QWidgetStack also provides the ability to manipulate widgets through application-specfied integer IDs, and to translate from widget pointers to IDs using id() and from IDs to widget pointers using widget(). These numeric IDs have and unique (per QWidgetStack, not globally) and cannot be -1, but apart from that QWidgetStack does not attach any meaning to them.
The default widget stack is frame-less and propagates its font and palette to all its children, but you can use the usual QFrame functions (like setFrameStyle()) to add a frame, and use setFontPropagation() and setPalettePropagation() to change the propagation style.
大致中文意思如下:
QWidgetStack类提供了一个只有最上面的窗口部件是用户可视的窗口部件的栈。
应用程序程序员可以在任何时候使用raiseWidget()把任何一个窗口部件移到栈顶,并且使用addWidget()和removeWidget()来添加或者移除窗口部件。
visibleWidget()是raiseWidget()的获取对应函数,它返回当前在栈顶的窗口部件的指针。
QWidgetStack也提供了通过应用程序指定的整数标识来维护这些窗口部件。你也可以使用id()来从窗口部件指针转换到标识并且使用widget()来从标识转换到窗口部件指针。这些数字标识是唯一的(每一个QWidgetStack,而不是全局的),但是QWidgetStack不会给它们添加额外的东西。
默认窗口部件栈是没有框架的,但是你可以使用通常的QFrame函数(比如setFrameStyle())来添加一个框架。
QWidgetStack提供一个信号aboutToShow(),在一个被管理的窗口部件被显示之前,这个信号被发射。
QWidgetStack 在任何情况下,这个QWidget栈中,只能有最上面的那个是可以显示出来的,其余的QWidget是影藏起来的。
我们要通过raiseWidget()来实现将某一个QWidget调出来显示。
void QWidgetStack::raiseWidget ( QWidget * w ) [slot]
Raises w to the top of the widget stack.
void QWidgetStack::raiseWidget ( int id ) [slot]
Raises id to the top of the widget stack
这个是这一阶段的关键。
startButton =newQPushButton(CHINESE_DISP(启动),this);
startButton->setBackgroundMode(QWidget::PaletteBase);
griLayout->addWidget(startButton,0,0);
setButton =newQPushButton(CHINESE_DISP(设置),this);
griLayout->addWidget(setButton, 1,0);
netButton =newQPushButton(CHINESE_DISP(网络),this);
griLayout->addWidget(netButton, 2,0);
stopButton =newQPushButton(CHINESE_DISP(停止),this);
griLayout->addWidget(stopButton, 3,0);
exitButton =newQPushButton(CHINESE_DISP(退出),this);
griLayout->addWidget(exitButton, 4,0);
connect(exitButton, SIGNAL(clicked()),qApp, SLOT(quit()));
connect(setButton, SIGNAL(clicked()), SLOT(setAct()));//按钮与对应插槽的连接
connect(netButton, SIGNAL(clicked()), SLOT(netAct()));
connect(stopButton, SIGNAL(clicked()), SLOT(stopAct()));
}
voidSystemMain::stopAct()//停止按钮对应的插槽
{
dispArea->raiseWidget(stopWget);
}
voidSystemMain::setAct()//设置按钮对应的插槽
{
dispArea->raiseWidget(setWget);
}
voidSystemMain::netAct()//网络按钮对应的插槽
{
dispArea->raiseWidget(netWget);
}
startButton = new QPushButton(CHINESE_DISP(启动), this);
startButton->setBackgroundMode(QWidget::PaletteBase);
griLayout->addWidget(startButton,0,0);
setButton = new QPushButton(CHINESE_DISP(设置), this);
griLayout->addWidget(setButton, 1,0);
netButton = new QPushButton(CHINESE_DISP(网络), this);
griLayout->addWidget(netButton, 2,0);
stopButton = new QPushButton(CHINESE_DISP(停止), this);
griLayout->addWidget(stopButton, 3,0);
exitButton = new QPushButton(CHINESE_DISP(退出), this);
griLayout->addWidget(exitButton, 4,0);
connect(exitButton, SIGNAL(clicked()),qApp, SLOT(quit()));
connect(setButton, SIGNAL(clicked()), SLOT(setAct())); //按钮与对应插槽的连接
connect(netButton, SIGNAL(clicked()), SLOT(netAct()));
connect(stopButton, SIGNAL(clicked()), SLOT(stopAct()));
}
void SystemMain::stopAct()//停止按钮对应的插槽
{
dispArea->raiseWidget(stopWget);
}
void SystemMain::setAct()//设置按钮对应的插槽
{
dispArea->raiseWidget(setWget);
}
void SystemMain::netAct()//网络按钮对应的插槽
{
dispArea->raiseWidget(netWget);
}
上述代码中CHINESE_DISP宏定义不用管,只是为了能在linux显示中文。
这一阶段的核心处理就是通过connect()连接信号,以setButton为例子:
connect(setButton, SIGNAL(clicked()), SLOT(setAct()));
connect(setButton, SIGNAL(clicked()), SLOT(setAct()));
将setButton点击之后的信号与setAct()函数连接。setAct()函数的就是使用了raiseWidget(),从而把相应的QWidget调出来显示。
这里各个按钮对应的QWidget需要自己实现。比如setWget。
总结:
QWidgetStack
raiseWidget
connect()
这是实现局部界面切换的核心函数。
并请联系谭海燕本人或者前往谭海燕个人主页留言