基于Qt4的图形用户界面程序的设计与实现
现代计算机(总第三○三期)
基于Qt4的图形用户界面程序的设计与实现
刘艳青1,苏桂莲2
(1.山东电子职业技术学院计算机系,济南250014;2.山东省农业管理干部学院计算机科学与技术系,济南250010)
摘要:
关键词:图形用户界面;Qt;信号与槽;事件
收稿日期:2009-01-05修稿日期:2009-03-01
作者简介:刘艳青(1974-),女,山东莱阳人,大学讲师,硕士,研究方向为图形图像处理、应用软件开发
Qt是一个跨平台的C++图形用户界面应用程序框架,得到了越来越广泛的应用。重点
对Qt的核心特性——
—信号与槽机制进行了分析,详细描述最新版本Qt4在构建图形界
面、事件处理等方面的优秀性能,通过一个具体的扫雷游戏实现进一步阐明Qt程序的
设计理念。
0引言
Qt使用源代码级“一次编写,随处编译”的方式
为开发跨平台的图形用户界面程序提供了一个完整
的C++应用程序开发框架,它完全面向对象,有良好
的封装机制,模块化程度高,可重用性好,容易扩展,
允许真正的组件编程,提供给应用程序开发者建立艺
术级图形用户界面所需的功能,提供了信号与槽的机
制替代回调函数,使组件间信号传递更安全、简单。
1Qt编程关键技术
1.1信号与槽
信号/槽机制是Qt的核心机制,主要用于实现对
象间的通信。一般的图形用户编程中采用回调函数进
行对象间通信如gtk+,但这样做没有信号和槽机制简
便和灵活。
槽是类的正常成员函数,唯一的特点就是它们可
以被信号连接。所有派生于QObject并且使用Signal-
Slot机制的类都必须包含一个Q_OBJECT宏。
1.2Qt事件处理
事件是由窗口系统或Qt自身产生的,例如当用
户按下或者松开键盘或者鼠标上的按键时,就可以产
生一个键盘或者鼠标事件;当某个窗口第一次显示的
时候,就会产生一个绘制事件,用来告知窗口需要重
新绘制它本身,从而使得该窗口可见。在Qt中,事件
就是QEvent子类的一个实例,例如鼠标按键事件既
需要保存是哪个按键激发了该事件的信息,又需要保
存发生该事件时鼠标指针所在的位置信息,这些信息
需要存储在专用的QEvent子类中,如QMouseEvent。
通过继承QObject,事件通过它们的event()函数来通
知对象,event()把绝大多数常用类型的事件提前传递
给特定的事件处理器,例如mousePressEvent(),
paintEvent(),重新实现mountPressEvent(),paintEvent()
等事件处理器是最常用的事件处理方式[2],本文介绍
的扫雷游戏设计就采用此种处理方式。在类的声明
中,重定义了QMainWindow类的3个鼠标事件方法:
mouseMoveEvent()、mousePressEvent()、mouseRelease-
Event(),分别是鼠标移动事件响应函数、鼠标按下事
件响应函数、鼠标松开事件响应函数。
2扫雷游戏设计与实现
2.1创建应用程序的界面
通过子类化QMainWindow创建扫雷游戏应用程
序用户界面。游戏需要提供一个菜单栏,提供游戏的
开始、结束、难度设置等选项。在游戏区按功能将它分
成雷区和提示区,提示区包括计数器、记时器和复位
按钮等对象。
Qt4使用“动作”的概念简化了有关菜单和工具
栏的编程。一个动作(action)就是一个可以添加到任
意菜单和工具栏上的项。在Qt4中,创建菜单和工具
栏可以按照步骤:创建并设置动作->创建菜单并把动
作添加到菜单上->创建工具栏并把动作添加到工具
栏上。在扫雷游戏中,当选择New game菜单项时,此貋貞財
M O D E R N C OM P U T E R2009.3
现代计算机(总第三
○
三
期)
M O D E R N C OM P U T E R 2009.3
动作触发槽函数initGame(),代码如下:
void MainWindow::createActions(){
newAct =new QAction(tr("&New game"),this);newAct->setShortcut(tr("Ctrl+N"));
newAct->setStatusTip(tr("Begin a new game"));connect (newAct,SIGNAL (triggered ()),this,SLOT
(initGame()));
……//其他动作的实现代码
}
在程序中,我们还使用信号/槽机制把复位按钮的clicked()信号与类MainWindow 的initGame()槽连接起来。代码如下:
connect (resetButton,SIGNAL (clicked ()),this,SLOT (initGame()));
2.2鼠标事件处理
游戏过程中,当玩家用鼠标点击相应的方块,程序就会作出相应的鼠标响应事件,程序处理这些鼠标事件来完成图形的绘制,因此需要对鼠标事件进行重定义。程序界面如图1所示。
图1Linux (Fedora 8)环境下的程序界面
MainWindow 类的定义如下:
class MainWindow :public QMainWindow {public:
MainWindow();
private slots://私有槽函数的声明void initGame();protected ://私有函数的声明void createActions();void createMenus();void createStatusBar();
void mousePressEvent (QMouseEvent *e );
void mouseReleaseEvent(QMouseEvent *e );void paintEvent(QPaintEvent *);//私有变量的声明QAction *newAct;QPixmap pixMap;//复位按钮对象的声明QpushButton resetButton;
……
}
下面是代码实现部分:
void MainWindow::mouseReleaseEvent (QMouseEvent *e ){
Qstring str="("+QString::number (e->x ())+","+QString::number(e->y())+")";
i=(e->x()-startX)/step;//(i ,j )为鼠标点击的雷区的方
块坐标。
j=(e->y ()-startY)/step;//(startX,startY)为雷区起始点,step 为雷方块大小。
if(e->button()==Qt::LeftButton)
{statusBar()->showMessage (tr("Left Button Released:")+str);
//处理鼠标左键}
if(e->button()==Qt::RightButton)
{statusBar()->showMessage (tr("Right Button Released:")+str);
//处理鼠标右键}update();}
调用update()函数重画雷区。要在窗口中画图,需
要重载虚方法paintEvent(),重新实现函数paintEvent()完成雷区的更新工作。Qt 的二维图形引擎基于
QPainter 类,它既可以绘制几何形状,也可以绘制像素映射、图像和文字。在进行绘图时,首先构造一个
QPainter 对象,只需调用drawPixmap()函数把相应像素绘制在雷区窗口上即可。QMouseEvent 类的x()和y
()方法可以获取鼠标的位置,button()方法可以获取发生鼠标事件的按键属性,例如左键或右键等。
void MainWindow::paintEvent(QPaintEvent *){
drawMineArea();}
void MainWindow::drawMineArea()
貋
貞貢
M O D E R N C OM P U T E R
2009.3
现代计算机(总第三
○
三期)
Design and Implementation of Graphical User
Interface Program Based on Qt4
LIU Yan-qing 1,SU Gui-lian 2
(1.Department of Computer,Shandong College of Electronic Technology,Jinan 250014;
2.Department of Computer Science and Technology,Shandong Agricultural Administrators College ,Jinan 250010)
Abstract :Keywords :Graphical User Interface ;Qt ;Signal-Slot ;Event
Qt is a multi -platform C ++graphical user interface application framework,it has been
widely used.Analyses the core characteristic of signal-slot mechanism,describes excellent performance of the latest version of Qt4in building GUI and event handling.Through a specific mine game realization,further clarifies the design concept for Qt program.
{//绘制雷区
QPainter painter(this);for (int i =0;i for (int j =0;j {//根据(i ,j )区域的雷方块信息数组m[i][j].curState 状态指示拷贝相应的图像到雷区的指定区域,像素大小为 16×16 QPixmap p1=pixMap.copy (0*16,m [i][j].curState*16,16,16);painter.drawPixmap (QPoint (startX +i*16,star -tY+j*16),p1); }}} 其中pixMap 是QPixmap 类的实例,在构造函数初始化时将图像文件装入内存,图像文件如图2所示。 MainWindow::MainWindow(){ …… createActions();createMenus();createStatusBar(); pixMap.load(":/images/state.png");...... connect(resetButton,SIGNAL(clicked()),this,SLOT(initGame()));......} 图2雷方块图像文件 3结语 本文重点对Qt 的核心特性———信号与槽机制进 行了分析,介绍了Qt 在构建图形界面、实现事件响应等方面的卓越特性,详细介绍了传统的扫雷游戏的设计与实现,Qt 的优越特性保证了本程序的高效性和跨平台性。随着时间的推移,使用Qt 来开发图形用户界面程序会变得越来越广泛。 参考文献 [1]Trolltech.Qt-Cross-Platform C++Development-Trolltech [EB/OL].2007.https://www.360docs.net/doc/8118665263.html,/products/qt/features/index. [2]Blanchette J,Summerfield M.C++GUI Programming with Qt 4,Second Edition[M].USA:Prentice Hall ,2006. [3]成杰等编著.Linux 窗口程序设计—Qt 精彩实例分析.北 京:清华大学出版社,2008 貋貞貣