⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qianb.txt

📁 本文介绍了如何使用qt提供的接口来设计自己的GUI风格(look and feel)
💻 TXT
📖 第 1 页 / 共 2 页
字号:
       中国 [ 选择]      使用条款 
   
 
 
   dW 全部内容-----------------  DB2  Lotus  Tivoli  WebSphere-----------------  Java 技术  Linux  Open source  Security  SOA & Web services  Web architecture  Wireless  XML-----------------IBM 全部内容             
 
 
      首页       产品       服务与解决方案       支持与下载       个性化服务        
 
 
 
developerWorks 中国 > Linux >    
 
 
 用QT创建新风格Howto    
  
 
 
   
内容: 
 
1.Qt的风格 
 
2.创建新风格 
 
3.使用新风格 
 
4.进一步工作 
 
参考资料  
 
关于作者 
 
对本文的评价 
 
 
 
订阅: 
 
developerWorks 时事通讯 
 
 
 
 
 
 
级别: 中级
 

姚延栋
研究生, 中国科学院软件所2002级
2003 年 11 月 

本文介绍了如何使用qt提供的接口来设计自己的GUI风格(look and feel),并通过一个具体的例子(使QSpinBox垂直显示)来详细说明过程。运行环境:redhat 9.0,qt-x11-free-3.2.*
1.Qt的风格
a) Qt简介 
Qt是一个跨平台的C++图形用户界面应用程序开发库,使用Qt可以开发出高质量的图形用户接口,它是完全面向对象的、易于扩展且允许真正的组件编程。 Qt获得了很大的成功,特别是它的信号-槽机制是非常值得研究的通信机制,它也是Linux发行版标准组件KDE(K Desktop Enviroment)的基础。 

b) 风格机制 
Qt的风格机制实现了不同平台上的图形用户接口(GUI)的观感(look and feel),例如Windows平台上通常使用Windows或Windows-xp风格,而Unix平台上通常使用Motif、CDE风格。 

下图显示了Qt中与风格相关的类的继承关系


 

QStyle 是所有风格类的基类,它控制着所有的部件(widget即windows编程中的控件)的界面风格或观感,它定义了大量的枚举类型和十几个函数。枚举类型表示界面上的不同元素(如组合框中的按钮,按钮的边框等);函数控制图形用户界面的绘制,但大多数函数基本上只是一些声明而没有函数实现,他们的实现在 QCommonStyle、QWindowStyle、QMotifStyle及其子类中。QStyle只实现了3个函数drawItem(), itemRect(), visualRect()。

drawItem(): 负责绘制文本和象素图。 
itemRect(): 返回文本或图像所占的区域。 
visualRect(): 返回逻辑坐标,这个函数使Qt实现right-to-left风格(阿文、维文传统是文本从右向左显示,因此控件布局也是从右向左)。如下图所示: 


 

可以看到菜单、工具条是右对齐、单选框的按钮在右边

c) 创建新风格的步骤 
在Qt中实现一种新风格的步骤很简单:只需选择一个风格类(如QCommonStyle或QStyle)作为父类,然后实现感兴趣的函数即可。难点在于函数的实现。 

选择父类:可以选择QStyle, QCommonStyle, QWindowStyle, QMotifStyle以及他们的子类的任意一个作为父类。通常可以选择QWindowsStyle或QMotifStyle,也可以选择 QCommonStyle甚至是QStyle,但是工作量会比较大,因为很多界面的细节需要自己实现。 

重新实现必要的函数:想修改界面风格的哪部分,就重新实现与绘制那部分相关的函数,下面解释一下我们要重载的QStyle中的几个函数,这几个函数控制着图形用户界面上不同元素的布局和观感。 


                        
1)void drawPrimitive( PrimitiveElement pe,
                    	 QPainter *p,
                        const QRect & r,
                        const QColorGroup & cg,
                        SFlags flags = Style_Default,
                        const QStyleOption &opt = QStyleOption::Default ) ;
                        
 

功能:绘制基本图形元素,如QSpinBox中的带箭头的按钮 等。 

参数: PrimitiveElement pe: 这个枚举型变量表示将要绘制的基本图形界面元素(这里说的基本图形用户界面元素指GUI中不可再分的一个原子元素,如组合框 


 

中的这个绘有黑色三角形的按钮,spinBox中的按钮 

 


QPainter *p:指向QPainter类的指针,Qt中的所有绘制操作不管是绘制文本、图形还是图像都由这个类来处理。 
QRect &r: 表示一个矩形区域,Qt在这个区域中绘制基本界面元素(PrimitiveElement). 
QColorGroup &cg: QColorGroup表示一个部件(widget)的颜色组(color group),color group含有部件绘制自己时使用的各种颜色,譬如前景色背景色等。下图展示了color group中的各种颜色属性 

 

SFlags flags: 控制如何绘制图形界面元素的标志。 
QStyleOption &opt: 绘制不同的部件(widget)时会需要不同的参数,如绘制面板(panel)可能需要线宽作为额外参数而绘制焦点矩形(focus rect)可能需要背景色作为额外参数,所以Qt专门提供了一个类QStyleOption来封装不同的widget可能需要的不同的参数,opt指向这样一个类的对象。 


2)void drawComplexControl( 	ComplexControl control,
			QPainter *p,
			const QWidget *widget,
			const QRect &r,
			const QColorGroup &cg,
			SFlags flags = Style_Default,
			SCFlags controls = QStyle::SC_All,
			SCFlags active = QStyle::SC_None,
			const QStyleOption& opt = QStyleOption::Default)
				       			
 

功能:绘制复杂控制部件(widget)如SpinWidget,comboBox,slider,listView等

参数:

ComplexControl control:是一个枚举量,表示将要绘制的复杂控制部件(widget)如组合框、列表框等。 
QPainter *p:指向QPainter的指针,Qt中的所有绘制操作不管是绘制文本、图形还是图像都由这个类来处理。 
QWidget *widget:指向QWdget或其子类的指针,可以根据上面control的值转变(cast)成合适的类型,例如如果要绘制 QSpinWidget,那么control取值为CC_SpinWidget,而widget指向一个QSpinWidget(QWidget的子类) 的实例(instance)。使用这个变量可以访问QSpinWidget的成员函数和成员变量,譬如可以调用QSpinWidget的sizeHint 函数获得这个部件的缺省大小(一个矩形空间)。 
QRect &r: 表示一个矩形区域,Qt在这个区域中绘制控件或其子部件。 
QColorGroup &cg: QColorGroup表示一个部件(widget)的颜色组(color group),color group含有部件绘制自己时使用的各种颜色,譬如前景色背景色等。 
SFlags flags: 控制如何绘制图形界面元素的标志 
SCFlags controls表示绘制复杂控制部件control的哪个子部件,缺省为SC_All,即绘制整个control而不是其某个子部件(注意control, controls是两个不同的参数) 
QStyleOption &opt: 在绘制不同的部件时可能需要不同的额外的参数,这个变量在绘制不同的widget时提供不同的信息。 

									
		3) QRect querySubControlMetrics(ComplexControl control,
    								const QWidget* widget,
									SubControl sc,
									const QStyleOption&
									 = QStyleOption::Default)
									
 

功能:获取子部件的坐标和尺寸信息。这个函数控制着一个复杂控件的布局,重载这个函数可以使的组合框的下拉按钮绘制在左边 而不是默认的右边。

参数: 
ComplexControl control: 枚举量,表示将要绘制的复杂控制部件(widget)如组合框、列表框等。 
QWidget *widget:指向QWidget或其子类的指针,可以根据上面control的值转变(cast)成合适的类型,例如如果要绘制 QSpinWidget,那么control取值为CC_SpinWidget,而widget指向一个QSpinWidget(QWidget的子类) 的实例。使用这个变量可以访问QSpinWidget的成员函数和成员变量,譬如可以调用QSpinWidget的sizeHint函数获得这个部件的缺省大小(一个矩形空间)。 
SubControl sc:枚举量,一个复杂部件可能由多个的子部件组成,使用sc变量说明要获取那个子部件的坐标和尺寸信息。 
QStyleOption &opt: 计算不同部件的尺寸时可能需要不同的额外信息,QStyleOption封装了这些信息。 

2.创建新风格
下面用一个例子来介绍一下创建新风格的整个过程,在编程之前,先看一下最终的结果是什么样的。(在Qt内部QSpinBox类是通过QSpinWidget实现的)

默认风格的效果:   使用新风格的效果:   

可以看到在新风格中我们的SpinBox有了垂直显示的效果。下面我们按上面说明的步骤来创建一种新的风格。

1)选择基类:我们选择QWindowsStyle类作为我们新风格类的基类,当然也可以选择QMotifStyle,在这个例子种也可以选择 QCommonStyle。一般不建议选择QCommonStyle作为基类,因为QCommonStyle只实现了一部分界面部件,如果要实现一个完整的风格类,我们需要重新写很多代码。

2)重载相关的函数:在这个例程中我们只修改了spinBox的风格,实现这个部件(widget)只与QStyle类的三个函数drawPrimitive, drawComplexControl, qureySubControlMerics相关,所以我们只需重载这三个函数的相关部分代码.下面对代码中的关键部分做一下注释,不重要的部分省略了。详细的代码可以从后面下载。

绘制spinbox中按钮的函数:


void CustomStyle::drawPrimitive( PrimitiveElement pe,
                        	QPainter * p,
                            const QRect & r,
                            const QColorGroup & cg,
                            SFlags flags,
                            const QStyleOption & opt ) const
{
/*PE_SpinWidgetUp,PE_SpinWidgetDown表示spinBox中的下按钮和上按钮,
下面的代码使得这两个按钮中的三角形分别向左和向右*/
if ((pe == PE_SpinWidgetUp) || (pe == PE_SpinWidgetDown)){
		int fw = pixelMetric( PM_DefaultFrameWidth, 0 );//fw表示边框宽度,默认为2
		QRect br;  //spinBox上按钮的边界矩形不是spinBox的边界矩形。
		br.setRect( r.x() + fw, r.y() + fw, r.width() - fw*2,
		    r.height() - fw*2 );
		p->fillRect( br, cg.brush( QColorGroup::Button ) );
		int x = r.x(), y = r.y(), w = r.width(), h = r.height();
		int sw = w-4;
		int sh = sw/2 + 2;      // Must have empty row at foot of arrow
		int sx = x + w / 2 - sw / 2 - 1;
		int sy = y + h / 2 - sh / 2 - 1;

		QPointArray a;
/* 设置三角形的三个点的坐标,修改这三个点可以使得QSpinBox上按钮里的三角型呈现任意的形状,
下面的设置使得三角形表示的箭头分别向左和向右。*/
		if ( pe == PE_SpinWidgetDown )
		    a.setPoints( 3,  0, sh/2,  sw-1, 1,  sw-1, sh-1 );
  	else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -