1.QSS

在网页前端开发领域中,CSS 是一个至关重要的部分,描述了一个网页的 “样式”,从而起到对网页美化的作用。所谓样式,包括不限于大小、位置、颜色、背景、间距、字体等等。

网页开发作为 GUI 的典型代表,也对于其他客户端 GUI 开发产生了影响,Qt 也是其中之一。Qt 仿照 CSS 的模式,引入了 QSS,来对 Qt 中的控件做出样式上的设定,从而允许程序猿写出界面更好看的代码。

同样受到 HTML 的影响,Qt 还引入了 QML 来描述界面,甚至还可以直接把一个原生的 html 页面加载到界面上。当然,由于 Qt 本身的设计理念和网页前端还是存在一定差异的,因此 QSS 中只能支持部分 CSS 属性,整体来说 QSS 要比 CSS 更简单一些。

注意:如果通过 QSS 设置的样式和通过 C++ 代码设置的样式冲突,则 QSS 优先级更高。

1.1基本语法

基本的语法结构

选择器 {属性名: 属性值;
}

其中:

  • 选择器 描述了 “哪个 widget 要应用样式规则”
  • 属性 则是一个键值对, 属性名表示要设置哪种样式, 属性值表示了设置的样式的值
QPushButton {color: red;
}

上述代码的含义表示, 针对界面上所有的 QPushButton , 都把文本颜色设置为红色

1.2指定控件样式设置

QWidget 中包含了 setStyleSheet 方法,可以直接设置样式

范围是pushButton_1控件及其所有子控件,进一步通过选择器选择的是QPushButton控件

将字体颜色设置为红色

范围是窗口及其所有子控件,进一步通过选择器选择的是QPushButton控件

将字体颜色设置为红色

我们是只针对这一个按钮通过 setStyleSheet 方法设置的样式,此时这个样式仅针对该按钮生效。如果创建其他按钮,其他按钮不会受到影响。

1.3设置全局样式

还可以通过 QApplication 的 setStyleSheet 方法设置整个程序的全局样式.

全局样式优点

  • 使同一个样式针对多个控件生效, 代码更简洁
  • 所有控件样式内聚在一起, 便于维护和问题排查

代码示例:样式的层叠特性

如果通过全局样式给某个控件设置了属性1,通过指定控件样式给控件设置属性2,那么这两个属性都会产生作用。

对于第一个按钮来说,同时具备了颜色和字体大小样式。而第二个按钮只有颜色样式,说明针对第一个按钮,两种设置方式设置的样式,叠加起来了。

形如上述这种属性叠加的效果,我们称为 “层叠性”。

代码示例: 样式的优先级

如果全局样式,和指定控件样式冲突,则指定控件样式优先展示。

运行程序, 观察效果,可以看到第一个按钮已经成为绿色了,但是第二个按钮仍然是红色。

在 CSS 中也存在类似的优先级规则. 通常来说都是 “局部” 优先级高于 “全局” 优先级,相当于全局样式先 “奠定基调” , 再通过指定控件样式来 "特事特办。

1.4 从文件加载样式表

上述代码都是把样式通过硬编码的方式设置的,这样使 QSS 代码和 C++ 代码耦合在一起了,如果QSS代码简单就无所谓了,一旦QSS代码复杂,继续这样写,以后的代码的维护代价非常的高。因此更好的做法是把样式放到单独的文件中,然后通过读取文件的方式来加载样式。

先创建一个.qss文件,将其导入到qrc中

编辑.qss文件

将.qss文件中的内容加载到代码中,写一个用于加载的函数

这个方案仅供参考,在实际开发中还有更方便的方案。

1.5使用 Qt Designer 编辑样式

QSS 也可以通过 Qt Designer 直接编辑,从而起到实时预览的效果,同时也能避免 C++ 和 QSS 代码的耦合。

代码示例: 使用 Qt Designer 编辑样式

1.在界面上创建一个按钮

    2.右键按钮, 选择 “改变样式表”

      3.在弹出的样式表编辑器中,可以直接填写样式,填写完毕,点击 OK 即可

        4. 此时 Qt Designer 的预览界面就会实时显示出样式的变化

          5. 运行程序,可以看到样式确实发生了改变

          这种方式设置样式, 样式内容会被以 xml 格式记录到 ui 文件中

          <property 1 name="styleSheet">
          <string notr="true">QPushButton { color: red; }</string>
          </property>
          

          同时在控件的 styleSheet 属性中也会体现

          当我们发现一个控件的样式不符合预期的时候,要记得排查这四个地方:

          • 全局样式
          • 指定控件样式
          • qss 文件中的样式
          • ui 文件中的样式

          1.6 选择器

          1.6.1 选择器概况

          QSS 的选择器支持以下几种:

          选择器示例说明
          全局选择器*选择所有的 widget
          类型选择器 (type selector)QPushButton选择所有的 QPushButton 和 其子类 的控件
          类选择器 (class selector).QPushButton 选择所有的QPushButton 的控件,不会选择子类
          **ID 选择器 **#pushButton_2选择 objectName 为pushButton_2 的控件
          子选择器QDialog>QPushButton选择 QDialog 的所有子控件中的QPushButton
          后代选择器QDialog QPushButton选择 QDialog 的所有后代(子控件, 孙子控件等等)中的 QPushButton
          **并集选择器 **QPushButton, QLineEdit,
          QComboBox
          选择 QPushButton, QLineEdit, QComboBox 这三种控件(即接下来的样式会针对这三种控件都生效)
          例如:可以写多个类型选择器、多个ID选择器
          属性选择器QPushButton[flat=“false”]选择所有 QPushButton 中,flat 属性为 false 的控件

          上述选择器也不需要全都掌握,只熟悉最常用的几个即可(上述加粗的)。

          1.6.2id 选择器

          1.在界面上创建 3 个按钮, objectName 为 pushButton , pushButton_2 , pushButton_3

          2.编写 main.cpp, 设置全局样式

          • 先通过 QPushButton 设置所有的按钮为黄色
          • 再通过 #pushButton 和 #pushButton_2 分别设置这两个按钮为红色和绿色

          执行程序, 观察效果

          当某个控件身上, 通过类型选择器和 ID 选择器设置了冲突的样式时, ID 选择器样式优先级更高。同理, 如果是其他的多种选择器作用同一个控件时出现冲突的样式, 也会涉及到优先级问题。实践中我们可以简单的认为,选择器描述的范围越精准, 则优先级越高。一般来说,ID 选择器优先级是最高的。

          1.6.3并集选择器

          1.创建按钮, label, 单行输入框

            2.编写 main.cpp, 设置全局样式

            1.6.4子控件选择器

            有些控件内部包含了多个 “子控件” ,比如 QComboBox 的下拉后的面板, 比如 QSpinBox 的上下按钮等,可以通过子控件选择器 ::,针对上述子控件进行样式设置。

            哪些控件拥有哪些子控件, 参考文档 Qt Style Sheets Reference 中 List of Sub-Controls 章节

            代码示例: 设置下拉框的下拉按钮样式

            1.在界面上创建一个下拉框, 并创建几个选项

              2.创建 resource.qrc , 并导入图片 down.png

              3.修改 main.cpp, 编写全局样式

              • 使用子控件选择器 QComboBox::down-arrow 选中了 QComboBox 的下拉按钮.
              • 再通过 image 属性设置图片.

                4.执行程序, 观察效果

                代码示例: 修改进度条的颜色

                1.在界面上创建一个进度条

                  2.在 Qt Designer 右侧的属性编辑器中, 找到 QWidget 的 styleSheet 属性

                  编辑如下内容:

                  • 其中的 chunk 是选中进度条中的每个 “块”,使用 QProgressBar::text 则可以选中文本
                  QProgressBar::chunk {background-1 color: #FF0000;}
                  

                  同时把 QProcessBar 的 alignment 属性设置为垂直水平居中

                  此处如果不设置 alignment,进度条中的数字会跑到左上角,这个怀疑是 Qt 本身的 bug,暂时只能先使用 alignment 来手动调整下。

                  3.执行程序, 可以看到如下效果,我们就得到了一个红色的进度条

                  通过上述方式,也可以修改文字的颜色,字体大小等样式。

                  1.6.5 伪类选择器(Pseudo-States)

                  伪类选择器, 是根据控件所处的某个状态被选择的. 例如按钮被按下, 输入框获取到焦点, 鼠标移动到某

                  个控件上等.

                  • 当状态具备时,控件被选中,样式生效
                  • 当状态不具备时,控件不被选中,样式失效

                  使用 : 的方式定义伪类选择器

                  常用的伪类选择器

                  伪类选择器说明
                  :hover鼠标放到控件上
                  :pressed鼠标左键按下时
                  :focus获取输入焦点时
                  :enabled元素处于可用状态时
                  :checked被勾选时
                  :read-only元素为只读状态时

                  这些状态可以使用 ! 来取反,比如 :!hover 就是鼠标离开控件时,:!pressed 就是鼠标松开时等等。

                  更多伪类选择器的详细情况,参考 Qt Style Sheets Reference 的 Pseudo-States 章节。

                  代码示例: 设置按钮的伪类样式.

                  1.在界面上创建一个按钮

                    2.编写 main.cpp, 创建全局样式

                    2.运行程序, 可以看到, 默认情况下按钮文字是红色, 鼠标移动上去是绿色, 鼠标按下按钮是蓝色

                      上述代码也可以使用事件的方式来实现

                      代码示例: 使用事件方式实现同样效果

                      1.创建 MyPushButton 类, 继承自 QPushButton

                      把生成代码中的构造函数改成带参数 QWidget* 版本的构造函数. (否则无法和 Qt Designer 生成的代码适配

                        mypushbutton.h

                        把生成代码中的构造函数改成带参数 QWidget* 版本的构造函数. (否则无法和 Qt Designer 生成的代码适配)

                        mypushbutton.h

                        #include 1 <QPushButton>
                        class MyPushButton : public QPushButton
                        {
                        public:MyPushButton(QWidget* parent);
                        };
                        

                        mypushbutton.cpp

                        #include "mypushbutton.h"
                        MyPushButton::MyPushButton(QWidget* parent) : QPushButton(parent)
                        {
                        }
                        

                        右键按钮, 选择 “提升为”

                        填写提升的类名和头文件

                        提升完毕后, 在右侧对象树这里, 就可以看到类型的变化

                          2.重写 MyPushButton 的四个事件处理函数

                          修改 mypushbutton.h

                          class MyPushButton : public QPushButton
                          {
                          public:MyPushButton(QWidget* parent);void mousePressEvent(QMouseEvent* e);void mouseReleaseEvent(QMouseEvent* e);void enterEvent(QEvent* e);void leaveEvent(QEvent* e);
                          };
                          

                          修改 mypushbutton.cpp

                          • 初始化设为红色
                          • 鼠标进入时设为绿色, 离开是还原红色.
                          • 鼠标按下时设为蓝色, 松开时还原绿色(松开时鼠标还是在按钮里)
                          1. 在界面上创建按钮,并提升为 MyPushButton 类型
                          MyPushButton::MyPushButton(QWidget* parent) : QPushButton(parent)
                          {this->setStyleSheet("QPushButton { color: red; }");
                          }
                          void MyPushButton::mousePressEvent(QMouseEvent *e)
                          {this->setStyleSheet("QPushButton { color: blue; }");
                          }
                          void MyPushButton::mouseReleaseEvent(QMouseEvent *e)
                          {this->setStyleSheet("QPushButton { color: green; }");
                          }
                          void MyPushButton::enterEvent(QEvent *e)
                          {this->setStyleSheet("QPushButton { color: green; }");
                          }
                          void MyPushButton::leaveEvent(QEvent *e)
                          {this->setStyleSheet("QPushButton { color: red; }");
                          }
                          

                            运行程序, 可以看到效果和上述案例一致

                            很明显,实现同样的功能,伪类选择器要比事件的方式简单很多,但是不能就说事件机制就不好. 事件可以完成的功能很多,不仅仅是样式的改变,还可以包含其他业务逻辑.,这一点是伪类选择器无法替代的。

                            1.7样式属性

                            QSS 中的样式属性非常多,不需要都记住,核心原则还是用到了就去查,大部分的属性和 CSS 是非常相似的,文档的 Qt Style Sheets Reference 章节详细介绍了哪些控件可以设置属性,每个控件都能设置哪些属性等。

                            在翻阅文档的时候涉及到一个关键术语 “盒模型” (Box Model)

                            一个遵守盒模型的控件, 由上述几个部分构成

                            • Content 矩形区域: 存放控件内容. 比如包含的文本/图标等
                            • Border 矩形区域: 控件的边框
                            • Padding 矩形区域: 内边距. 边框和内容之间的距离
                            • Margin 矩形区域: 外边距. 边框到控件 geometry 返回的矩形边界的距离

                            默认情况下, 外边距, 内边距, 边框宽度都是 0

                            可以通过一些 QSS 属性来设置上述的边距和边框的样式

                            QSS 属性说明
                            margin设置四个方向的外边距,复合属性
                            padding设置四个方向的内边距,复合属性
                            border-style设置边框样式
                            border-width边框的粗细
                            border-color边框的颜色
                            border复合属性, 相当于 border-style + border-width + border-color

                            代码示例: 设置边框和内边距

                            1.

                                           

                            1.修改 main.cpp, 设置全局样式

                            • border: 5px solid red 相当于 border-style: solid;border-width: 5px;border-color: red三个属性的简写形式
                            • padding-left: 10px是给左侧设置内边距

                            2.运行程序,可以看到样式发生了变化

                            代码示例: 设置外边距

                            为了方便确定控件位置, 演示外边距效果, 我们使用代码创建一个按钮

                            1.修改 widget.cpp, 创建按钮, 并设置样式

                              2.运行程序, 可以看到, 当前按钮的边框被外边距挤的缩小了. 但是获取到的按钮的 Geometry 是不变的

                              1.8控件样式示例

                              1.8.1按钮

                              代码示例:自定义按钮

                              1.界面上创建一个按钮

                                2.右键 -> 改变样式表,使用 Qt Designer 设置样式

                                属性小结

                                属性说明
                                font-size设置文字大小
                                border-radius设置圆角矩形,数值设置的越大,角就 “越圆”
                                background-color设置背景颜色

                                运行程序,可以看到此时的复选框就变的丰富起来了

                                1.8.2 复选框

                                代码示例: 自定义复选框

                                1.创建一个 resource.qrc 文件,并导入以下图片

                                • 使用黑色作为默认形态
                                • 使用蓝色作为 hover 形态
                                • 使用红色作为 pressed 形态

                                  2.创建一个复选框

                                  3.编辑复选框的样式

                                    QCheckBox {font-size: 20px;
                                    }
                                    QCheckBox::indicator {width: 20px;height: 20px;
                                    }
                                    QCheckBox::indicator:unchecked {image: url(:/checkbox-unchecked.png);
                                    }
                                    QCheckBox::indicator:unchecked:hover {image: url(:/checkbox-unchecked_hover.png);
                                    }
                                    QCheckBox::indicator:unchecked:pressed {image: url(:/checkbox-unchecked_pressed.png);
                                    }
                                    QCheckBox::indicator:checked {image: url(:/checkbox-checked.png);
                                    }
                                    QCheckBox::indicator:checked:hover {image: url(:/checkbox-checked_hover.png);
                                    }
                                    QCheckBox::indicator:checked:pressed {image: url(:/checkbox-checked_pressed.png);
                                    }
                                    

                                    4.运行程序, 观察效果

                                    小结:

                                    要点说明
                                    ::indicator子控件选择器,选中 checkbox 中的对钩部分
                                    :hover伪类选择器,选中鼠标移动上去的状态
                                    :pressed伪类选择器,选中鼠标按下的状态
                                    :checked伪类选择器,选中 checkbox 被选中的状态
                                    :unchecked伪类选择器,选中 checkbox 未被选中的状态
                                    width设置子控件宽度,对于普通控件无效 (普通控件使用 geometry 方式设定尺寸)
                                    height设置子控件高度,对于普通控件无效 (普通控件使用 geometry 方式设定尺寸)
                                    image设置子控件的图片,像 QSpinBox, QComboBox 等可以使用这个属性来设置子控件的图片

                                    1.8.3 单选框

                                    代码示例: 自定义单选框

                                    1.创建 resource.qrc 文件, 并导入以下图片

                                    • 使用黑色作为默认形态
                                    • 使用蓝色作为 hover 形态
                                    • 使用红色作为 pressed 形态

                                      2.在界面上创建两个单选按钮

                                        3.在 Qt Designer 中编写样式

                                        此处为了让所有 QRadioButton 都能生效,把样式设置在 Widget 上了,并且使用后代选择器选中了 QWidget 里面的 QRadioButton。

                                        QWidget QRadioButton {font-size: 20px;
                                        }
                                        QWidget QRadioButton::indicator {width: 20px;height: 20px;
                                        }
                                        QWidget QRadioButton::indicator:unchecked {image: url(:/radio-unchecked.png);
                                        }
                                        QWidget QRadioButton::indicator:unchecked:hover {image: url(:/radio-unchecked_hover.png);
                                        }
                                        QWidget QRadioButton::indicator:unchecked:pressed {image: url(:/radio-unchecked_pressed.png);
                                        }
                                        QWidget QRadioButton::indicator:checked {image: url(:/radio-checked.png);
                                        }
                                        QWidget QRadioButton::indicator:checked:hover {image: url(:/radio-checked_hover.png);
                                        }
                                        QWidget QRadioButton::indicator:checked:pressed {image: url(:/radio-checked_pressed.png);
                                        }
                                        
                                          要点说明
                                          ::indicator子控件选择器,选中 radioButton 中的对钩部分
                                          :hover伪类选择器,选中鼠标移动上去的状态
                                          :pressed伪类选择器,选中鼠标按下的状态
                                          :checked伪类选择器,选中 radioButton 被选中的状态
                                          :unchecked伪类选择器,选中 radioButton 未被选中的状态
                                          width设置子控件宽度,对于普通控件无效 (普通控件使用 geometry 方式设定尺寸)
                                          height设置子控件高度,对于普通控件无效 (普通控件使用 geometry 方式设定尺寸)
                                          image设置子控件的图片,像 QSpinBox, QComboBox 等可以使用这个属性来设置子控件的图片

                                          1.8.4输入框

                                          代码示例: 自定义单行编辑框

                                          1.在界面上创建一个单行编辑框

                                          2.在 Qt Designer 中编写样式

                                            QLineEdit {border-width: 1px;border-radius: 10px;border-color: rgb(58, 58, 58);border-style: inset;padding: 0 8px;color: rgb(255, 255, 255);background:rgb(100, 100, 100);selection-background-color: rgb(187, 187, 187);selection-color: rgb(60, 63, 65);
                                            }
                                            

                                              3.执行程序观察效果

                                              属性说明
                                              border-width设置边框宽度
                                              border-radius设置边框圆角
                                              border-color设置边框颜色
                                              border-style设置边框风格
                                              padding设置内边距
                                              color设置文字颜色
                                              background设置背景颜色
                                              selection-background-color设置选中文字的背景颜色
                                              selection-color设置选中文字的文本颜色

                                              1.8.5 列表

                                              代码示例: 自定义列表框

                                              1.在界面上创建一个 ListView

                                              2.编写代码

                                                QListView::item:hover {background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #FAFBFE, stop: 1 #DCDEF1);
                                                }
                                                QListView::item:selected {border: 1px solid #6a6ea9;background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #6a6ea9, stop: 1 #888dd9);
                                                }

                                                  3.执行程序, 观察效果

                                                  要点说明
                                                  ::item选中 QListView 中的具体条目
                                                  :hover选中鼠标悬停的条目
                                                  :selected选中某个被选中的条目
                                                  background设置背景颜色
                                                  border设置边框
                                                  qlineargradient设置渐变色

                                                  qlineargradient 有 6 个参数

                                                  x1, y1: 标注了一个起点

                                                  x2, y2: 标注了一个终点.

                                                  这两个点描述了一个 “方向”

                                                  stop0 和 stop1 描述了两个颜色. 渐变过程就是从 stop0 往 stop1 进行渐变的

                                                  例如:

                                                  • x1: 0, y1: 0, x2: 0, y2: 1 就是垂直方向从上向下 进行颜色渐变
                                                  • x1: 0, y1: 0, x2: 1, y2: 0 就是水平方向从左向右 进行颜色渐变
                                                  • x1: 0, y1: 0, x2: 1, y2: 1 就是从左上往右下方向 进行颜色渐变

                                                  1.8.6 菜单栏

                                                  1.创建菜单栏

                                                  2.编写样式

                                                    QMenuBar {background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 lightgray, stop:1 darkgray);spacing: 3px; /* spacing between menu bar items */
                                                    }
                                                    QMenuBar::item {padding: 1px 4px;background: transparent;border-radius: 4px;
                                                    }
                                                    QMenuBar::item:selected { /* when selected using mouse or keyboard */background: #a8a8a8;
                                                    }
                                                    QMenuBar::item:pressed {background: #888888;
                                                    }
                                                    QMenu {background-color: white;margin: 0 2px; /* some spacing around the menu */
                                                    }
                                                    QMenu::item {padding: 2px 25px 2px 20px;border: 3px solid transparent; /* reserve space for selection border */
                                                    }
                                                    QMenu::item:selected {border-color: darkblue;background: rgba(100, 100, 100, 150);
                                                    }
                                                    QMenu::separator {height: 2px;background: lightblue;margin-left: 10px;margin-right: 5px;
                                                    }

                                                      3.执行程序, 观察效果

                                                      要点说明
                                                      QMenuBar::item选中菜单栏中的元素
                                                      QMenuBar::item:selected选中菜单来中的被选中的元素
                                                      QMenuBar::item:pressed选中菜单栏中的鼠标点击的元素
                                                      QMenu::item选中菜单中的元素
                                                      QMenu::item:selected选中菜单中的被选中的元素
                                                      QMenu::separator选中菜单中的分割线

                                                      1.8.7登录界面

                                                      给界面创建元素

                                                      此时界面布局不够整齐、不够合理,通过布局管理器进行调整

                                                      添加垂直布局管理器

                                                      此时会发现各个控件大小不合理

                                                      设置Line Edit最大高度和最小高度都为40,此时Line Edit的高度固定为40像素

                                                      同样设置QPushButton的宽度和高度设置为90*30像素

                                                      给窗口设置一个背景

                                                      直接想法,是给顶层窗口设置背景图,但是Qt存在限制,直接给顶层窗口设置背景会失效。

                                                      给顶层窗口创建一个同样大小的QFrame的子对象,QFrame相对于QWidget提供了更多的功能,比如设置形状、设置样式。

                                                      在Qt中除了background-image设置背景图除了,还有border-image来设置背景图,推建使用border-image来设置背景图设置背景图,通过border-image设置的背景图根据窗口大小同步的变化,而background-image设置背景图是固定大小。

                                                      设置背景后的界面效果

                                                      设置了背景图还不够,针对上面的控件还需要在样式上进一步设计。

                                                      这里统一在QWidget上进行样式的修改

                                                      1.设置输入框样式

                                                      编写 QSS 代码

                                                        2.设置 checkbox 样式

                                                        背景色使用 transparent 表示完全透明 (应用父元素的背景)

                                                          3.设置按钮样式

                                                          4.为了让用户明却输入的是什么,设置placeholderText属性

                                                            5.密码框中的内容默认是不显示的,设置隐藏

                                                              选择密码框,找到echoMode选项,选择Password

                                                              2.绘图

                                                              虽然 Qt 已经内置了很多的控件, 但是不能保证现有控件就可以应对所有场景,很多时候我们需要更强的 “自定制” 能力。所谓的 “控件” , 本质上也是通过画图的方式画上去的,控件是对画图 API 的进一步封装,画图 API 是控件的底层实现。

                                                              和绘图相关的类

                                                              说明
                                                              QPainter“绘画者” 或者 “画家”,用来绘图的对象,提供了一系列 drawXXX 方法,可以允许我们绘制各种图形。
                                                              QPaintDevice“画板”,描述了 QPainter 把图形画到哪个对象上. 像咱们之前用过的 QWidget 也是一种 QPaintDevice (QWidget 是 QPaintDevice 的子类) 。
                                                              QPen“画笔”,描述了 QPainter 画出来的线是什么样的。
                                                              QBrush“画刷”,描述了 QPainter 填充一个区域是什么样的。

                                                              绘图 API 的使用,一般不会在 QWidget 的构造函数中使用, 而是要放到 paintEvent 事件中。

                                                              paintEvent 会在以下情况下被触发:

                                                              • 控件首次创建
                                                              • 控件被遮挡, 再解除遮挡
                                                              • 窗口最小化,再恢复
                                                              • 控件大小发生变化时
                                                              • 主动调用 repaint() 或者 update() 方法. (这两个方法都是 QWidget 的方法)

                                                              2.1绘制线段

                                                              示例1:

                                                              void drawLine(const QPoint &p1, const QPoint &p2);
                                                              参数:
                                                              p1:绘制起点坐标
                                                              p2:绘制终点坐标
                                                              

                                                              示例2:

                                                              void drawLine ( int x1, int y1, int x2, int y2 );
                                                              参数:
                                                              x1,y1:绘制起点坐标
                                                              x2,y2:绘制终点坐标
                                                              

                                                                1.在 “widget.h” 头文件中声明绘图事件

                                                                  2.在 “widget.cpp” 文件中重写 paintEvent() 方法

                                                                  实现效果如下:

                                                                  2.2绘制矩形

                                                                  void QPainter::drawRect(int x, int y, int width, int height);
                                                                  参数:
                                                                  x:窗口横坐标;
                                                                  y:窗口纵坐标;
                                                                  width:所绘制矩形的宽度;
                                                                  height:所绘制矩形的高度;
                                                                  

                                                                  2.3 绘制圆形

                                                                  void QPainter::drawEllipse(const QPoint &center, int rx, int ry)
                                                                  参数:
                                                                  center:中心点坐标
                                                                  rx:横坐标
                                                                  ry:纵坐标
                                                                  

                                                                  实现效果:

                                                                  2.4 绘制文本

                                                                  QPainter类中不仅提供了绘制图形的功能,还可以使用drawText() 函数来绘制文字,也可以使用setFont() 设置字体等信息。

                                                                  实现效果如下:

                                                                  2.5 设置画笔

                                                                  QPainter 在绘制时,是有一个默认的画笔的。在使用时也可以自定义画笔。在 Qt 中,QPen类中定义

                                                                  了 QPainter 应该如何绘制形状、线条和轮廓。同时通过 QPen类 可以设置画笔的线宽、颜色、样式、

                                                                  画刷等。

                                                                  画笔的颜色可以在实例化画笔对象时进行设置,画笔的宽度是通过 setWidth() 方法进行设置,画笔的

                                                                  风格是通过setStyle()方法进行设置,设置画刷主要是通过 setBrush() 方法。

                                                                  • 设置画笔颜色:QPen::QPen(const QColor &color) 画笔的颜色主要是通过 QColor 类设置;
                                                                  • 设置画笔宽度:void QPen::setWidth(int width)
                                                                  • 设置画笔风格:void QPen::setStyle(Qt::PenStyle style)

                                                                  画笔的风格有:

                                                                  实现效果如下:

                                                                  2.6 设置画刷

                                                                  在 Qt 中,画刷是使用 QBrush类 来描述,画刷大多用于填充。QBrush定义了QPainter的填充模式,具有样式、颜色、渐变以及纹理等属性。

                                                                  画刷的格式中定义了填充的样式,使用 Qt::BrushStyle 枚举,默认值是 Qt::NoBrush,也就是不进行任何填充。可以通过 Qt 助手查找画刷的格式。

                                                                  实现效果:

                                                                  2.7绘制图片

                                                                  其实绘制图片本质上是将图片显示到控件上。

                                                                  2.7.1绘制基础图片

                                                                  2.7.2图片旋转

                                                                  2.7.3QImage、QPixmap、QBitmap 和 QPicture的区别

                                                                  Qt 提供了四个类来处理图像数据:QImage、QPixmap、QBitmap 和 QPicture,它们都是常用的绘图设备。

                                                                  • QImage主要用来进行 I/O 处理,它对 I/O 处理操作进行了优化,而且可以用来直接访问和操作像素;
                                                                  • QPixmap 主要用来在屏幕上显示图像,它对在屏幕上显示图像进行了优化;
                                                                  • QBitmap是 QPixmap 的子类,用来处理颜色深度为1的图像,即只能显示黑白两种颜色;
                                                                  • QPicture 用来记录并重演 QPainter 命令。

                                                                  本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
                                                                  如若转载,请注明出处:http://www.pswp.cn/pingmian/92632.shtml
                                                                  繁体地址,请注明出处:http://hk.pswp.cn/pingmian/92632.shtml
                                                                  英文地址,请注明出处:http://en.pswp.cn/pingmian/92632.shtml

                                                                  如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

                                                                  相关文章

                                                                  week1+2+3

                                                                  408 计组 1.基本组成2.数据的表示和运算定点数&#xff1a;把数字分为定点整数和定点小数分开存储 浮点数&#xff1a;用科学计数法存储 原码 -全部取反-> 反码 反码 1->补码 补码 -符号位取反->移码带余除法&#xff1a;设x,m∈Z&#xff0c;m>0则存在唯一的整数q…

                                                                  java8中javafx包缺少报错

                                                                  今天拉取一个jdk1.8的项目里面有一个代码用到了javafx&#xff0c;这个我记得是jdk中的包&#xff0c;正常不应该报错的。然后发现jdk中还真没有&#xff0c;查了一下是因为版本问题。 Java 8 及之前&#xff1a;Oracle JDK 自带 JavaFX&#xff0c;OpenJDK 通常不包含Java 9 …

                                                                  day072-代码检查工具-Sonar与maven私服-Nexus

                                                                  文章目录0. 老男孩思想-选对池塘钓美人鱼1. 代码回滚方案2. SonarQube2.1 代码检查工具2.2 部署sonarqube2.2.1 软件要求2.2.2 安装软件2.2.3 启动sonar2.2.4 部署插件2.3 sonar检查java代码2.3.1 创建sona项目2.3.2 分析java代码2.3.3 Jenkins结合sonar检查代码2.4 sonar检查非…

                                                                  【前端基础】15、列表元素、表格元素、表单元素(注:极其粗略的记载。)

                                                                  一、列表元素 1、什么是列表元素2、有序列表&#xff08;ol、li&#xff09; ol有序列表 直接子元素只能是li。 li列表中的每一项。3、无序列表&#xff08;ul、li&#xff09; ol无序列表 直接子元素只能是li。 li列表中的每一项。4、定义列表&#xff08;dl、dt、dd&#xff…

                                                                  IRFBG30PBF Vishay威世MOSFET场效应管

                                                                  IRFBG30PBF Vishay威世&#xff1a;超快MOSFET 场效应管一、产品定位IRFBG30PBF 是Vishay威世推出的600V/30A N沟道功率MOSFET&#xff0c;采用第五代TrenchFET技术&#xff0c;专为开关电源、电机驱动、新能源逆变器等高功率场景设计。以85mΩ超低导通电阻和超快反向恢复&…

                                                                  【07-AGI的讨论】

                                                                  AI ANI&#xff1a;artificial narrow intelligence; 如 智能音箱&#xff1b;自动驾驶汽车&#xff0c;网络搜索&#xff0c;其他用于专业特定事项的工具&#xff1b; AGI&#xff1a;artificial general intelligence; building AI systems that could do anything a typical…

                                                                  [激光原理与应用-225]:机械 - 3D图与2D图各自的作用

                                                                  在机械设计与加工领域&#xff0c;3D图和2D图是两种核心的工程表达方式&#xff0c;它们在产品设计、制造、装配及维护等环节中扮演不同角色&#xff0c;具有互补性。以下是它们各自的作用及具体应用场景的详细解析&#xff1a;一、3D图的作用1. 直观展示产品全貌三维可视化&am…

                                                                  【从零开始java学习|第一篇】java中的名词概念(JDK、JVM、JRE等等)

                                                                  目录 一、核心运行环境三要素&#xff08;JVM/JRE/JDK&#xff09; 二、常用开发指令&#xff08;JDK 自带工具&#xff09; 三、一些其他概念 四、总结核心逻辑链 要入门 Java&#xff0c;理解核心概念之间的关系是基础。以下是 Java 中最核心的基础概念、工具及相关名词的…

                                                                  UVa12345 Dynamic len(set(a[L:R]))

                                                                  [TOC](UVa12345 Dynamic len(set(a[L:R]))) 题目链接 UVA - 12345 Dynamic len(set(a[L:R])) 题意 有编号从 0 到 n−1 的 n 个数&#xff0c;有两种操作&#xff1a; Q L R 询问编号 L 到编号 R−1 的数中有多少个不同的数字。M X Y 将编号为 X 的数字改为 Y。 你的任务就是…

                                                                  [Ubuntu] VNC连接Linux云服务器 | 实现GNOME图形化

                                                                  将桌面环境修改为 GNOME 并通过 VNC 远程访问的步骤 & TightVNC 的安装与配置说明&#xff1a;1. 安装 GNOME 桌面环境 sudo apt update sudo apt install ubuntu-gnome-desktop -y2. 安装 TightVNC 服务器 sudo apt install tightvncserver -y3. 初始化 VNC Server 并设置…

                                                                  进程、网络通信方法

                                                                  一、进程间通信(IPC)方法 适用于同一台主机上的进程间数据交换。 管道(Pipe) 匿名管道:单向通信,仅用于父子进程。 命名管道(FIFO):通过文件系统路径访问,支持无亲缘关系进程。 消息队列(Message Queue) 结构化消息(类型+数据),按类型读取,支持异步通信。…

                                                                  [激光原理与应用-241]:设计 - 266n皮秒深紫外激光器,哪些因素影响激光器紫外光的输出功率?

                                                                  一、短期稳定性266nm皮秒深紫外激光器紫外光输出功率的稳定性受非线性晶体性能、光学系统设计、热管理效果、重复频率与脉冲能量匹配度、环境干扰控制等因素影响&#xff0c;具体分析如下&#xff1a;1. 非线性晶体性能晶体选择与状态&#xff1a;BBO&#xff08;偏硼酸钡&…

                                                                  Django配置sqllite之外的数据库

                                                                  当连接到其他数据库后端时&#xff0c;如 MariaDB、MySQL、Oracle 或 PostgreSQL&#xff0c;将需要额外的连接参数。请参阅下面的 ENGINE 配置&#xff0c;了解如何指定其他数据库类型。这个例子是针对 PostgreSQL&#xff1a; 在django项目的settings.py文件里&#xff0c;关…

                                                                  银河通用招人形机器人强化学习算法工程师了

                                                                  人形强化学习算法工程师&#xff08;26届&#xff09;&#xff08;岗位信息已通过jobleap.cn授权&#xff0c;可在csdn发布&#xff09;银河通用机器人 北京收录时间&#xff1a; 2025年08月11日职位描述1. 研发基于深度强化学习的足式机器人运动控制算法&#xff0c;提升机器…

                                                                  使用MongoDB存储和计算距离

                                                                  一、MongoDB 计算距离的优势 优势说明原生地理空间索引支持 2dsphere 索引&#xff0c;高效处理地理坐标查询&#xff08;毫秒级响应&#xff09;。内置地理计算函数提供 $near、$geoWithin、$geoNear 等操作符&#xff0c;无需手动实现复杂计算。高性能基于B树索引优化&#…

                                                                  鸿蒙开发-ArkUI中@Type作用详细解答

                                                                  在鸿蒙&#xff08;HarmonyOS&#xff09;应用开发中&#xff0c;Type 是 ArkUI 框架中用于 类型定义和类型检查 的关键注解&#xff08;装饰器&#xff09;。它的主要作用是为自定义组件的属性提供明确的类型约束&#xff0c;确保数据传递的类型安全性。 核心作用解析&#xf…

                                                                  MCU中的存储器映射(Memory Map)

                                                                  MCU中的存储器映射(Memory Map) 在MCU(微控制器单元)中,存储器映射(Memory Map)是指将不同类型的存储器(如Flash、RAM、外设寄存器等)和功能模块分配到统一的地址空间的过程。这种映射方式使得CPU可以通过访问特定地址来读写数据或控制外设,而无需关心物理存储介质的…

                                                                  Rust面试题及详细答案120道(11-18)-- 控制流与函数

                                                                  《前后端面试题》专栏集合了前后端各个知识模块的面试题&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

                                                                  数据结构-排序(2)

                                                                  一、堆排序 &#xff08;借助树&#xff09;1.利用完全二叉树构建大顶堆 2.堆顶元素和堆底元素进行交换&#xff0c;堆底元素不再参与构建&#xff0c;剩余元素继续构建大顶堆3.时间复杂度 O(nlogn)1.完全二叉树&#xff1a;按照从上到下&#xff0c;从左到右的顺序进行排序2.…

                                                                  Qt-信号和槽

                                                                  一.信号和槽概念1. 信号&#xff08;Signal&#xff09;概念&#xff1a;信号是 Qt 对象在状态发生变化或事件发生时自动发出的通知。比如按钮被点击、文本框内容变化、定时器超时等&#xff0c;都会发出相应信号。本质&#xff1a;它只是一个函数声明&#xff08;没有函数体&a…