首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

linux嵌入式下的QT图形界面开发(2)

linux嵌入式下的QT图形界面开发(2)

2.2.1 信号与插槽的例子
如果一个类要使用信号与插槽机制,它就必须是从QObject或者QObject的子类继承,而且在类的定义中必须加上Q_OBJECT宏。信号被定义在类的信号部分,而插槽则定义在public slots, protected slots 或者 private slots 部分。
下面定义一个使用到信号与插槽机制的类。
class BankAccount : public QObject
{
Q_OBJECT
public:
BankAccount() { curBalance = 0; }
int balance() const { return curBalance; }
public slots:
void setBalance( int newBalance );
signals:
void balanceChanged( int newBalance );
private:
int curBalance;
};
和大部分的C++的类一样,BankAccount类有一个构造函数,还有一个取值的函数balance(),一个设置值的函数setBalance( int newBalance )。这个类有一个信号balanceChanged(),这个信号声明了它在BankAccount类的成员curBalance的值被改变时产生。信号不需要被实现,当信号被激发时,和该信号连接的插槽将被执行。上面用来设置值的函数setBalance( int newBalance )定义在类的“public slots”部分,因此它是一个插槽。插槽是一个需要实现的标准的成员函数,它可以像其它函数一样被调用,也可以和信号相连接。
下面就是该插槽函数setBalance( int newBalance )的实现代码:
void BankAccount::setBalance( int newBalance )
{
if ( newBalance != curBalance )
{
curBalance = newBalance;
emit balanceChanged( curBalance );
}
}
其中的一段代码
emit balanceChanged( curBalance );
它的作用是当curBalance 的值被改变后,将新的curBalance 的值作为参数去激活balanceChanged()信号。对于关键词“emit”,它和信号、插槽一样是由Qt 提供的,这些关键词都会被c++的预处理机制转换为c++代码。一个对象的信号可以被多个不同的插槽连接,而多个信号也可以被连接到相同的插槽。当信号和插槽被连接起来时,应当确保它们的参数类型是相同的,如果插槽的参数个数小于和它连接在一起的信号的参数个数,那么从信号传递插槽的多余的参数将被忽略。

2.2.2 元对象编译器
信号与插槽机制是以纯C++代码来实现的,实现的过程使用到了Qt 开发工具包提供的预处理器和元对象编译器(moc)。moc 读取应用程序的头文件,并产生支持信号与插槽的必要的代码。开发者没必要编辑或是浏览这些自动产生的代码,当有需要时,qmake 生成的Makefile 文件里会显式的包含了运行moc 的规则。除了可以处理信号与插槽机制之外,moc 还支持翻译机制,属性系统和运行时的信息。

2.3 窗体
Qt 拥有丰富的满足不同需求的窗体(按钮,滚动条等等),Qt 的窗体使用起来很灵活,为了满足特别的要求,它很容易就可以被子类化。窗体是Qwidget类或它子类的实例,客户自己的窗体类需要从Qwidget它的子类继承。
图二 摘录的Qwidget 类的继承图
一个窗体可以包含任意数量的子窗体,子窗体可以显示在父窗体的客户区,一个没父窗体的窗体我们称之为顶级窗体(一个“窗口”),一个窗体通常有一个边框和标题栏作为装饰。Qt 并未对一个窗体有什么限制,任何类型的窗体可以是顶级窗体,任何类型的窗体可以是别的窗体的子窗体。在父窗体显示区域的子窗体的位置可以通过布局管理自动的进行设置,也可以人为的指定。当父窗体无效,隐藏或被删除后,它的子窗体都会进行同样的动作。标签,消息框,工具栏等等等,并未被限制使用什么颜色,字体和语言。Qt的文本呈现窗体可以使用HTML子集显示一个多语言的宽文本。

2.3.1 一个Hello 的例子
下面是一个显示“Hello Qt/Embedded!”的程序的完整的源代码:
图三 Hello Qt/Embedded
#include <qapplication.h>
#include <qlabel.h>
int main( int argc, char **argv )
{
QApplication app( argc, argv );
QLabel *hello = new QLabel( "<font color=blue>Hello"
" <i>Qt/Embedded!</i></font>", 0 );
app.setMainWidget( hello );
hello->show();
return app.exec();
}

2.3.2 通用窗体
下面是一些主要的Qt 窗体的截屏图,这些窗体使用了窗口样式。
图四 使用了QHBox 进行排列一个标签和一个按钮
图五 使用了QbuttonGroup的两个单选框和两个复选框
图六 使用了QgroupBox进行排列的的日期类QDateTimeEdit, 一个行编辑框类QLineEdit, 一个文本编辑类QTextEdit 和一个组合框类QComboBox
图七 以QGrid排列的一个 QDial, 一个QProgressBar, 一个QSpinBox, 一个QScrollBar, 一个QLCDNumber和一个QSlider
图八 以QGrid排列的一个QIconView, 一个 QListView, 一个 QListBox 和一个 QTable有些时候在进行字符输入时,我们希望输入的字符满足了某种规则才能使输入被确认。Qt提供了解决的办法,例如QComboBox, QLineEdit 和 QspinBox 的字符输入可以通过Qvalidator的子类来进行约束和有效性检查。通过继承QScrollView ,QTable, QListView, QTextEdit 和其它窗体就能够显示大量的数据,并且自动的拥有了一个滚动条。许多Qt创建的窗体能够显示图像,例如按钮,标签,菜单项等等。Qimage类支持几种图形格式的输入、输出和操作,它目前支持的图形格式有BMP, GIF*, JPEG, MNG, PNG, PNM, XBM和 XPM。
2.3.3 画布
QCanvas 类提供了一个高级的平面图形编程接口,它可以处理大量的像线条、矩形、椭圆、文本、位图、动画等这些画布项,画布项可以较容易的做成交互式的(例如做成支持用户移动的)。画布项是QcanvasItem子类的实例,它们比窗体类Qwidget更显得轻量级,它们能够被快速的移动,隐藏和显示。Qcanvas可以更有效的支持冲突检测,它能够列出一个指定区域里面的所有的画布项。QcanvasItem可以被子类化,从而可以提供更多的客户画布项类型,或者扩展已有的画布项的功能。Qcanvas对象是由QcanvasView进行绘制的,QcanvasView对象可以以不同的译文、比例、旋转角度,剪切方式去显示同一个画布。Qcanvas 对象是理想的数据表现方式,它已经被消费者用于绘制地图和显示网络拓扑结构。它也可用于制作快节奏的且有大量角色的平面游戏。图九 在Qtopia 中用QCanvas 实现的小行星游戏

2.3.4 客户窗体
通过对Qwidget或者它的子类进行子类化,我们可以建立自己的客户窗体或者对话框。下面是一个完整的源代码例子,它示例了如何通过子类化窗体,绘制一个模拟的时钟。AnalogClock 窗体类是Qwidget的子类,它显示当前时间,并且可以自动地更新时间。
图十 模拟钟窗体
在 analogclock.h头文件中, AnalogClock 以这样地形式定义::
#include <qwidget.h>
class AnalogClock : public QWidget
{
public:
AnalogClock( QWidget *parent = 0, const char *name = 0 );
protected:
virtual void timerEvent( QTimerEvent *event );
virtual void paintEvent( QPaintEvent *event );
};
继承事业,薪火相传
返回列表