Qt中如何通过QStyle自定义能够跨平台的界面控件

转载 2012年03月23日 11:16:33

我们经常会碰到需要定制界面控件的要求。如果只是在一个平台上,比如说你的控件只需要在Windows上显示,那很好办,Hard code 你的look and feel就可以了。但是如果界面需要在不同平台上显示native的界面风格,比如在Windows上就是Windows的风格,Mac上就是Mac的风格,难道需要为每个平台写不同的代码吗?另外,如果是在Qt这个平台上你需要修改整体的界面风格,同时你的程序也需要跨平台,那你可能需要为每个平台派生该平台下的QStyle对象(Windows上有QWindowsXPStyle,QVistaStyle,Mac上有QMacStyle,等等)。同样修改之后也需要将修改应用到其他平台上。有更好的解决方案吗?

回答是肯定的。 首先你可以参照这篇有点老的文章“http://doc.trolltech.com/qq/qq09-q-and-a.html#style ”,使用Proxy Pattern来实现。创建一个Proxy,然后定义一个指向当前平台的style实例,这样就可以很容易的做一些定制。不过创建Proxy的过程可能有一些繁琐,后期也需要根据QStyle的更新进行维护。Proxy是一个在Qt中使用的非常广泛的pattern,如果你对proxy pattern不熟悉的话,可以去Wiki上看看简要的说明。当然这种方法也存在一些问题。其中最大的一个问题,当调用被代理style的函数时,比如 MyProxyStyle::DrawControl会去调用QWindowXPStyle::DrawControl,但是在DrawControl返回之前,后者永远只会调用QWindowXPStyle里面的函数,那我Proxy中customize的行为是得不到调用的。其实这个问题一直都是存在的,现在依然存在。那如何解决呢?

方案1:依然使用Proxy模式, 比如“这里 ”提供的方法。假设现在的需求是:为所有快捷方式显示下划线。方法如下:

首先创建一个PorxyStyle,不过不是QStyle的子类。是不是认为这样错了呢?怎么可能创建新的Style但是不从QStyle派生,那有多少工作需要做啊?不过请耐心往下看。ProxyStyle的代码如下:

  1. class ProxyStyle 
  2. public
  3.     ProxyStyle(const QString &baseStyle) { style = QStyleFactory::create(baseStyle); } 
  4.     int proxyStyleHint(QStyle::StyleHint hint, const QStyleOption *option = 0, 
  5.                              const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const 
  6.     { 
  7.         if (hint == QStyle::SH_UnderlineShortcut) 
  8.             return 1; 
  9.         return style->styleHint(hint, option, widget, returnData); 
  10.     } 
  11. private
  12.     QStyle *style; 
  13. }; 

然后这么我们真正自定义的Style这样来实现:

  1. #define ADDSTYLESUBCLASS(BaseStyleClass, BaseStyleName)  
  2. class My##BaseStyleClass : public BaseStyleClass, public ProxyStyle  
  3. public
  4.     My##BaseStyleClass() : BaseStyleClass(), ProxyStyle(BaseStyleName) {} 
  5.     int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const 
  6.     { 
  7.         return proxyStyleHint(hint, option, widget, returnData); 
  8.     } 
  9. }; 

这样你可以通过下面的宏来简单的实现对不同平台Sytle的定义,如果下次Windows 7的Style出现自了Qt中,你只需要加上一行代码便能解决所有的问题:

  1. ADDSTYLESUBCLASS(QCleanlooksStyle, "cleanlooks"); 
  2. ADDSTYLESUBCLASS(QPlastiqueStyle, "plastique"); 
  3. ADDSTYLESUBCLASS(QMotifStyle, "motif"); 
  4. ADDSTYLESUBCLASS(QWindowsStyle, "windows"); 
  5. ADDSTYLESUBCLASS(QCDEStyle, "cde"); 

方案2:“动态”继承

动态继承的方法很简单,相信你看到会眼前一亮。主要是利用模板的特性。可以这样来写你的新的Style:

  1. template<typename T> 
  2. class MyQStyle : public
  3. public
  4.     MyQStyle() : T() {} 
  5.     ~MyQStyle() {} 
  6.     virtual void drawItemText(…) { … } 
  7.     virtual int pixelMetric(…) { … } 
  8.     … 
  9. }; 
  10. QStyle* get_application_style(const QString& style_name) 
  11.     if( style_name == “windows”){ 
  12.         return new MyQStyle<QWindowsXPStyle>; 
  13.     } else if( style_name == “mac”){ 
  14.         return new MyQStyle<QMacStyle>; 
  15.     } … 
  16.     cerr ; 

看到了吧,是不是很方便啊?动态继承没有使用proxy,因此减少了很多不必要的代码,但是同时动态继承也有其缺点:它必须通过模板部分特例话的方法来处理不同的QWindowsXPStyle,QMacStyle中不同的函数名带来的编译问题。不过我还是很倾向于动态继承的方法。

Qt中如果通过QStyle自定义能够跨平台的界面控件

我们经常会碰到需要定制界面控件的要求。如果只是在一个平台上,比如说你的控件只需要在Windows上显示,那很好办,Hard code 你的look and feel就可以了。但是如果界面需要在不同平台...
  • aladdina
  • aladdina
  • 2009年06月06日 12:27
  • 4650

零基础学Qt 4编程实例之如何设置Qt应用程序的观感-使用QStyle类

Qt样式表是专为设置应用程序的观感(look and feel)而生的,它是从Qt 4.2开始引入的描述窗口部件观感的强大机制,允许你按照自己的需求定制应用程序的观感。并且从Qt 4.5开始,Qt样式...
  • qter_wd007
  • qter_wd007
  • 2011年03月12日 19:01
  • 11955

Qt对基本控件进行美化 QStyle和QStyleSheet

1使用QStyle QStyle是一个抽象类 定义了控件如何画出来。可以继承这个类实现一些Draw方法来构建某个style 最后对于控件调用QWidget->SetStyle 或者全局使用...
  • groundhappy
  • groundhappy
  • 2016年07月27日 16:27
  • 2643

Qt 和MFC对比及Qt跨平台优势

一.Qt的优势: 1.跨平台 2.signal-slot机制太漂亮了,与MFC相比,其非窗体类也支持该机制,这点设计者的想法让人佩服,并且由于其非窗体类也支持该机制,所以其很多用法让人感觉眼前一...
  • dch4890164
  • dch4890164
  • 2011年03月14日 17:07
  • 13919

QT中在MainWindow中代码添加控件

感谢 http://blog.csdn.net/noodle123/article/details/8260693 代码如下: MainWindow::MainWindow(QWidget *pare...
  • ljt350740378
  • ljt350740378
  • 2015年12月04日 16:14
  • 5966

Qt学习笔记外观篇(二):QStyle

三种方法来重新定义Qt内置窗口部件的外观: 1)子类化QStyle或者一个预定义的风格,这种方法很好用,Qt本身就是用这种方法为它所支持的不同平台提供基于平台的外观的 2)子类化个别的窗口部件类,...
  • wangyanphp
  • wangyanphp
  • 2014年08月13日 11:27
  • 5951

使用QT做跨平台编程

前两周,各种课程设计和实验,各种团队活动占据了我几乎所有的时间,睡觉都没啥时间,更不用说写博客了。 今天下午刚刚投出高频课设的PCB,暂时得以清闲,赶紧来写写博客,待我整理完微机原理的课设,后面的课设...
  • tankery
  • tankery
  • 2011年01月10日 21:28
  • 5797

Qt在mainwindow下代码添加控件不能显示的问题

以前在dialog或者widget下代码添加控件能显示,但是今天发现在mainwindow下居然不能显示,后来查了资料才知道,需要先定义一个widget,具体代码如下: QWidget *c...
  • sjt091110317
  • sjt091110317
  • 2015年11月16日 16:21
  • 1779

QT界面美化之QStyle

 转贴: http://www.cppblog.com/umbcom/QT中的QStyle类提供了对QT应用程序界面的封装,QT本身也是利用它应对不同平台下的界面外观的。例如 在windowxp下 你...
  • achellies
  • achellies
  • 2010年01月04日 09:26
  • 7702

Qt自定义控件以及控件的提升

关于在使用Qt做界面时,通用、常用的控件重复设置属性是件麻烦的事情,比如密码输入框,一个密码输入框要设置许多属性,比如密文显示,长度,只能输入固定字符类型,禁止复制等等,一个项目里面有时会用到很多密码...
  • y396397735
  • y396397735
  • 2017年11月05日 19:13
  • 132
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Qt中如何通过QStyle自定义能够跨平台的界面控件
举报原因:
原因补充:

(最多只允许输入30个字)