一、前言
最近项目正在进行QT开发,UI主要用QSS形式,主要针对windows和linux平台,开发流程为在windows上开发大概成品后,部署到linux环境上。过程中发现,QT对于windows和linux不同平台,UI呈现形式不同,碰到各种奇怪问题,这边对QT各类问题及用到的QSS进行总结,并设计一种基于现有xml形式的UI结构,方便后续QT界面模块开发。后续也会对另一种QML形式的GUI进行学习总结,方便混合开发。
【debug问题点】:QT QSS GUI
【环境】:windows linux
【使用工具】:QT
二、QSS语法总结
2.1、常见方法
2.1.1、Qt Designer
如上图,可以通过 右键按钮->改变样式表 或者 右边属性框中的styleSheet 访问到控件的样式表,进行QSS编写。
使用该方式的好处在于,可以直观看到设计效果,通过Ctrl+R就可以预览窗体设计。并且在编辑样式表窗口中添加资源、添加渐变、添加颜色、添加字体,方便直接编辑特定样式的颜色。
【!!!重点】:此类方式编辑的样式表默认作用于当前控件及其所有子控件,符合QT 父子控件继承的设计思想,当然QT也提供了相应QSS语法,能够屏蔽掉继承的影响,详见2.2.3选择器。
2.1.2、QSS文件读写
使用QFile读入样式表,使用setStyleSheet进行设置。对不同控件生效的示例代码如下:
QApplication app(argc, argv);
QFile qss("StyleSheet.qss");
qss.open(QFile::ReadOnly);
/* 此通过加载StyleSheet文件,对整个软件的所有控件样式进行设置。*/
app.setStyleSheet(qss.readAll());
/* 对单一类的ui对象设计样式。*/
this->setStyleSheet(qss.readAll());
/* 对ui对象中的控件设计样式。*/
ui->pushButton->setStyleSheet(qss.readAll());
qss.close();
【!!!重点】:上面两种方法的本质,其实都是通过setStyleSheet接口将带有QSS语法的字符串设置进控件。可以看见:
第一种方法,QT会在ui文件中自动生成:pushButton->setStyleSheet(QString::fromUtf8("xxx");
第二种方法则是通过读取文件内容进行设置,显示调用setStyleSheet。
2.2、常见语法
2.2.1、基础语法
QSS同CSS语法规则类似,形式如下:
selector {
attribute:value
};
其中:
selector选择器:通常情况下为控件类名(如QPushButton);
attribute属性:待设置的样式表属性(如background-color);
value值:属性赋值(如rgb(40, 85, 20););
2.2.2、共享属性
QCheckBox,QComboBox,QSpinBox{
color:rgb(255,0,0);
background-color:rgb(255,255,255);
font:bold;
}
这样就设置了所有作用范围内的QCheckBox、QComboBox、QSpinBox的前景色、背景色和字体。
2.2.3、选择器(selector)
Qt样式表支持CSS2中定义的所有选择器。下表总结了最有用的选择器类型。
2.2.4、伪状态(Pseudo-States)
用户在操作时,可以根据不同的交互状态展示不同的用户样式,界面能够识别用户操作,不需要代码控制即可响应不同状态下的样式。例如:
QPushButton {
border: 1px solid #555;
padding: 4px;
min-width: 65px;
min-height: 12px;
}
/* 悬浮效果 */
QPushButton:hover {
background-color: #999;
}
/* 按下效果 */
QPushButton:pressed {
background-color: #333;
border-color: #555;
color: #AAA;
}
常见的控件效果可以自行百度,基本是用到啥查啥,这里不赘述。
三、通用UI结构设计
待更新
四、常见问题分析
4.1、QT在不同操作系统呈现不同样式,控件效果不同,为什么?
答:QT在不同平台默认的样式QStyle不同,QT内置组件都是通过QStyle来进行绘制,通过设置内置样式能够保证在不同运行平台绘制的效果一致。
在linux系统下,通过qDebug() << QStyleFactory::keys();
打印了(“Windows”, “Fusion”);
系统默认是’Fusion’风格,就是特别奇怪的那种风格,comboBox控件的下拉界面坐标位置显示也不对。
我们可以通过下面代码将风格设置成windows。
ui->comboBox->setStyle(QStyleFactory::create("Windows"));
4.2、QT在windows下全局坐标正常,为什么Linux下坐标会乱飘?
答:暂时没有查到非常有效的原理解释,不过在项目开发中发现了一些规律。
1)在类构造函数中,如果去setGeometry或者move设置控件坐标,可能会导致控件坐标不准确。这可能是因为在构造中QT有些初始化工作没有做完,导致计算坐标数据不对。可以在构造后进行重新设置。
2)在对继承QWidget类型的窗口,show进行显示的上下文代码中,进行move设置坐标,windows下是正常的。
但是linux环境下,先move后show的代码,会导致控件位置乱飘。需要使用先show后move的代码顺序。这可能是因为show接口内部可能对控件坐标进行了更新,导致坐标不准;在show后进行move,等于重新进行坐标计算。