Qt——升级系列(Level Eight):界面优化

目录

QSS

  背景介绍

  基本语法

  QSS设置方式

        指定控件样式设置

        全局样式设置

        从文件加载样式表

        使用Qt Designer 编辑样式

  选择器

        选择器概况

        子控件选择器

        伪类选择器

  样式属性

        盒模型

  控件样式示例

        按钮

        复选框、单选框

        输入框

        列表

        菜单栏

        登录界面

绘图

  基本概念

  绘制各种形状

        绘制线段

        绘制矩形

        绘制圆形

        绘制文本

        设置画笔

        设置画刷

  绘制图片

        绘制简单图片

        缩放图片

        旋转图片

  特殊的画图设备

        QPixmap

        QImage

        QPicture

QSS

  背景介绍

        在⽹⻚前端开发领域中, CSS 是⼀个⾄关重要的部分. 描述了⼀个⽹⻚的 "样式". 从⽽起到对⽹⻚美化的作⽤.

        Qt 仿照 CSS 的模式, 引⼊了 QSS, 来对 Qt 中的控件做出样式上的设定, 从⽽允许程序员写出界⾯更好看代码.

        QSS(Qt Style Sheets)是Qt中用于定义和定制界面样式的一种机制。类似于CSS(Cascading Style Sheets),QSS允许开发者通过简单的语法规则为Qt应用程序的控件(如窗口、按钮、标签等)设置样式,从而实现界面的美化和个性化定制。

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

  基本语法

        对于 CSS 来说, 基本的语法结构⾮常简单.

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

        QSS 沿⽤了这样的设定.  

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

 其中:
        • 选择器 描述了 "哪个 widget 要应⽤样式规则".
        • 属性 则是⼀个键值对, 属性名表⽰要设置哪种样式, 属性值表⽰了设置的样式的值.

下面是一个典型的 Qt 程序中用于设置界面样式的示例:

Widget::Widget(QWidget *parent): QWidget(parent),  // 构造函数的初始化列表,将 parent 作为父类的构造函数参数ui(new Ui::Widget)  // 创建了 Ui::Widget 对象的实例,通常是在 Qt Designer 生成的 UI 类
{ui->setupUi(this);  // 调用 setupUi 函数初始化界面,将当前 Widget 作为参数传递// 为 QPushButton 设置样式表,使其文字颜色为红色ui->pushButton->setStyleSheet("QPushButton { color: red; }");
}

  QSS设置方式

        指定控件样式设置

        QWidget 中包含了 setStyleSheet ⽅法, 可以直接设置样式.上述代码我们已经演⽰了上述设置⽅式.

        另⼀⽅⾯, 给指定控件设置样式之后, 该控件的⼦元素也会受到影响.

代码⽰例: ⼦元素受到影响

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 创建一个父级 QWidgetQWidget parentWidget;parentWidget.setWindowTitle("Parent Widget");parentWidget.setGeometry(100, 100, 300, 200);// 创建一个垂直布局管理器QVBoxLayout layout(&parentWidget);// 创建一个 QPushButton 作为父级控件的子元素QPushButton *button1 = new QPushButton("Button 1", &parentWidget);layout.addWidget(button1);// 创建另一个 QPushButton 作为父级控件的子元素QPushButton *button2 = new QPushButton("Button 2", &parentWidget);layout.addWidget(button2);// 设置父级控件的样式表,同时会影响其所有子元素parentWidget.setStyleSheet("QWidget { background-color: lightblue; }""QPushButton { color: white; background-color: green; }");parentWidget.show();return app.exec();
}

代码结果:

        全局样式设置

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

全局样式优点:
        • 使同⼀个样式针对多个控件⽣效, 代码更简洁.
        • 所有控件样式内聚在⼀起, 便于维护和问题排查.

代码⽰例: 使⽤全局样式

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 设置全局样式表QString globalStyleSheet = "QWidget { background-color: lightblue; }""QPushButton { color: white; background-color: green; }";app.setStyleSheet(globalStyleSheet);// 创建一个父级 QWidgetQWidget parentWidget;parentWidget.setWindowTitle("Parent Widget");parentWidget.setGeometry(100, 100, 300, 200);// 创建一个垂直布局管理器QVBoxLayout layout(&parentWidget);// 创建一个 QPushButton 作为父级控件的子元素QPushButton *button1 = new QPushButton("Button 1", &parentWidget);layout.addWidget(button1);// 创建另一个 QPushButton 作为父级控件的子元素QPushButton *button2 = new QPushButton("Button 2", &parentWidget);layout.addWidget(button2);parentWidget.show();return app.exec();
}

代码结果: 

        从文件加载样式表

        上述代码都是把样式通过硬编码的⽅式设置的. 这样使 QSS 代码和 C++ 代码耦合在⼀起了, 并不⽅便代码的维护.

        因此更好的做法是把样式放到单独的⽂件中, 然后通过读取⽂件的⽅式来加载样式.

代码⽰例: 从⽂件加载全局样式

/* styles.qss *//* 设置所有 QWidget 的背景颜色为浅蓝色 */
QWidget 
{background-color: lightblue;
}/* 设置所有 QPushButton 的文字颜色为白色,背景颜色为绿色 */
QPushButton 
{color: white;background-color: green;
}
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QFile>
#include <QTextStream>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 读取样式表文件QFile styleFile(":/styles.qss");  // 文件路径可以根据实际情况修改if (!styleFile.open(QFile::ReadOnly | QFile::Text)) {qWarning("无法打开样式表文件");return -1;}// 读取样式表内容QTextStream textStream(&styleFile);QString styleSheet = textStream.readAll();// 关闭文件styleFile.close();// 设置全局样式表app.setStyleSheet(styleSheet);// 创建一个父级 QWidgetQWidget parentWidget;parentWidget.setWindowTitle("Parent Widget");parentWidget.setGeometry(100, 100, 300, 200);// 创建一个 QPushButton 作为父级控件的子元素QPushButton *button1 = new QPushButton("Button 1", &parentWidget);button1->resize(100, 30);button1->move(50, 50);// 创建另一个 QPushButton 作为父级控件的子元素QPushButton *button2 = new QPushButton("Button 2", &parentWidget);button2->resize(100, 30);button2->move(50, 100);parentWidget.show();return app.exec();
}

 代码结果:

        使用Qt Designer 编辑样式

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

  选择器

        选择器概况

        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 这三种控件.
属性选择器
QPushButton[flat="false"]
选择所有 QPushButton 中, flat 属性为 false 的控件.

使⽤类型选择器选中⼦类控件 :

int main(int argc, char *argv[])
{QApplication a(argc, argv);// 设置全局样式a.setStyleSheet("QWidget { color: red; }");Widget w;w.show();return a.exec();
}

 使⽤ id 选择器:

int main(int argc, char *argv[])
{QApplication a(argc, argv);// 设置全局样式QString style = "";style += "QPushButton { color: yellow; }";style += "#pushButton { color: red; }";style += "#pushButton_2 { color: green; }";a.setStyleSheet(style);Widget w;w.show();     return a.exec();
}

使⽤并集选择器 :

int main(int argc, char *argv[])
{QApplication a(argc, argv);// 设置全局样式a.setStyleSheet("QPushButton, QLabel, QLineEdit { color: red; } ");Widget w;w.show();return a.exec();
}

        子控件选择器

        有些控件内部包含了多个 "⼦控件" . ⽐如 QComboBox 的下拉后的⾯板, ⽐如 QSpinBox 的上下按钮等.

        可以通过⼦控件选择器 :: , 针对上述⼦控件进⾏样式设置.

使用子控件选择器设置 QComboBox 的下拉按钮样式:

#include <QApplication>
#include <QWidget>
#include <QComboBox>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 创建一个父级 QWidgetQWidget parentWidget;parentWidget.setWindowTitle("Parent Widget");parentWidget.setGeometry(100, 100, 300, 200);// 创建一个 QComboBox 控件作为父级控件的子元素QComboBox comboBox(&parentWidget);comboBox.setGeometry(50, 50, 200, 30);// 添加一些选项comboBox.addItem("Option 1");comboBox.addItem("Option 2");comboBox.addItem("Option 3");// 设置 QComboBox 的样式表,包括下拉按钮的样式comboBox.setStyleSheet("QComboBox::down-arrow {""    image: url(:/down_arrow.png);""    width: 20px;""    height: 20px;""}");parentWidget.show();return app.exec();
}

如何修改 QProgressBar 进度条的颜色,以及如何使用子控件选择器对其进行定制: 

#include <QApplication>
#include <QWidget>
#include <QProgressBar>
#include <QVBoxLayout>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 创建一个父级 QWidgetQWidget parentWidget;parentWidget.setWindowTitle("Parent Widget");parentWidget.setGeometry(100, 100, 300, 200);// 创建一个垂直布局管理器QVBoxLayout layout(&parentWidget);// 创建一个 QProgressBar 进度条控件作为父级控件的子元素QProgressBar *progressBar = new QProgressBar(&parentWidget);progressBar->setRange(0, 100); // 设置进度条范围progressBar->setValue(50);     // 设置当前进度layout.addWidget(progressBar);// 设置 QProgressBar 的样式表,修改进度条颜色和样式progressBar->setStyleSheet("QProgressBar {""    border: 2px solid grey;""    border-radius: 5px;""    text-align: center;""    background-color: #FFFFFF;""}""QProgressBar::chunk {""    background-color: #00FF00;""    width: 20px;""}");parentWidget.show();return app.exec();
}

        伪类选择器

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

• 当状态具备时, 控件被选中, 样式⽣效.
• 当状态不具备时, 控件不被选中, 样式失效.
使⽤ : 的⽅式定义伪类选择器。

常⽤的伪类选择器:

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

        这些状态可以使⽤ ! 来取反. ⽐如 :!hover 就是⿏标离开控件时, :!pressed 就是⿏标松开时,等等. 

示例1:设置按钮的伪类样式(使用样式表)

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 创建一个父级 QWidgetQWidget parentWidget;parentWidget.setWindowTitle("Parent Widget");parentWidget.setGeometry(100, 100, 300, 200);// 创建一个垂直布局管理器QVBoxLayout layout(&parentWidget);// 创建一个 QPushButton 按钮控件作为父级控件的子元素QPushButton *button = new QPushButton("Click me", &parentWidget);layout.addWidget(button);// 设置 QPushButton 的样式表,使用伪类选择器button->setStyleSheet("QPushButton {""    background-color: blue;""    color: white;""}""QPushButton:hover {""    background-color: lightblue;""}""QPushButton:pressed {""    background-color: darkblue;""}");parentWidget.show();return app.exec();
}

代码结果: 

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

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QEvent>class CustomButton : public QPushButton
{
public:CustomButton(QWidget *parent = nullptr) : QPushButton(parent) {}protected:void enterEvent(QEvent *event) override{setStyleSheet("background-color: lightblue;");}void leaveEvent(QEvent *event) override{setStyleSheet("background-color: blue;");}void mousePressEvent(QMouseEvent *event) override{setStyleSheet("background-color: darkblue;");QPushButton::mousePressEvent(event);}void mouseReleaseEvent(QMouseEvent *event) override{setStyleSheet("background-color: blue;");QPushButton::mouseReleaseEvent(event);}
};int main(int argc, char *argv[])
{QApplication app(argc, argv);// 创建一个父级 QWidgetQWidget parentWidget;parentWidget.setWindowTitle("Parent Widget");parentWidget.setGeometry(100, 100, 300, 200);// 创建一个垂直布局管理器QVBoxLayout layout(&parentWidget);// 创建一个自定义按钮控件作为父级控件的子元素CustomButton *button = new CustomButton(&parentWidget);button->setText("Click me");layout.addWidget(button);parentWidget.show();return app.exec();
}

代码结果:

  样式属性

        QSS 中的样式属性⾮常多, 不需要都记住. 核⼼原则还是⽤到了就去查.
        ⼤部分的属性和 CSS 是⾮常相似的.

        盒模型

⼀个遵守盒模型的控件, 由上述⼏个部分构成.
        • Content 矩形区域: 存放控件内容. ⽐如包含的⽂本/图标等.
        • Border 矩形区域: 控件的边框.
        • Padding 矩形区域: 内边距. 边框和内容之间的距离.
        • Margin 矩形区域: 外边距. 边框到控件 geometry 返回的矩形边界的距离
默认情况下, 外边距, 内边距, 边框宽度都是0.

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

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

 代码⽰例: 设置边框和内边距、设置外边距

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QHBoxLayout>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 创建一个主窗口QWidget mainWindow;mainWindow.setWindowTitle("Qt Style Sheets 示例");// 创建一个按钮QPushButton button("按钮示例", &mainWindow);// 使用布局管理按钮位置QHBoxLayout layout;layout.addWidget(&button);mainWindow.setLayout(&layout);// 设置样式mainWindow.setStyleSheet("QPushButton {""    border: 2px solid #000000; /* 设置边框 */""    padding: 10px; /* 设置内边距 */""    margin: 20px; /* 设置外边距 */""}");mainWindow.show();return app.exec();
}

代码结果: 

  控件样式示例

        改变样式表, 使⽤ Qt Designer 设置样式

        按钮

QPushButton 
{background-color: #4CAF50; /* 设置背景颜色为绿色 */border: none; /* 去掉边框 */color: white; /* 文字颜色为白色 */padding: 10px 20px; /* 设置内边距 */text-align: center; /* 文字居中显示 */text-decoration: none; /* 去掉文字下划线 */display: inline-block; /* 行内块元素 */font-size: 16px; /* 设置字体大小 */margin: 4px 2px; /* 设置外边距 */cursor: pointer; /* 鼠标移上去显示手型 */border-radius: 8px; /* 设置圆角 */
}

        复选框、单选框

QCheckBox::indicator, QRadioButton::indicator 
{width: 20px; /* 设置指示器宽度 */height: 20px; /* 设置指示器高度 */
}QCheckBox::indicator:checked, QRadioButton::indicator:checked 
{background-color: #2196F3; /* 设置选中时的背景颜色 */
}

        输入框

QLineEdit 
{padding: 8px; /* 设置内边距 */border: 1px solid #ccc; /* 设置边框 */border-radius: 5px; /* 设置圆角 */
}QLineEdit:hover 
{border-color: #4CAF50; /* 鼠标移上去时边框颜色变为绿色 */
}

        列表

QListWidget 
{background-color: #f2f2f2; /* 设置背景颜色为灰色 */padding: 10px; /* 设置内边距 */border: 1px solid #ccc; /* 设置边框 */border-radius: 5px; /* 设置圆角 */
}

        菜单栏

QMenuBar 
{background-color: #333; /* 设置背景颜色为深灰色 */color: white; /* 设置文字颜色为白色 */
}QMenuBar::item 
{spacing: 3px; /* 设置项之间的间距 */padding: 1px 4px; /* 设置内边距 */background-color: transparent; /* 背景透明 */color: white; /* 文字颜色为白色 */
}QMenuBar::item:selected 
{background-color: #4CAF50; /* 选中时的背景颜色为绿色 */
}

        登录界面

QWidget 
{background-color: #f2f2f2; /* 设置背景颜色为灰色 */
}QLineEdit, QPushButton 
{border-radius: 3px; /* 设置圆角 */padding: 8px; /* 设置内边距 */border: 1px solid #ccc; /* 设置边框 */
}QPushButton 
{background-color: #4CAF50; /* 设置背景颜色为绿色 */color: white; /* 文字颜色为白色 */
}QPushButton:hover 
{background-color: #45a049; /* 鼠标移上去时背景颜色变深 */
}

绘图

  基本概念

        虽然 Qt 已经内置了很多的控件, 但是不能保证现有控件就可以应对所有场景.

        很多时候我们需要更强的 "⾃定制" 能⼒.

        Qt 提供了画图相关的 API, 可以允许我们在窗⼝上绘制任意的图形形状, 来完成更复杂的界⾯设计.

注意:

        所谓的 "控件" , 本质上也是通过画图的⽅式画上去的.

        画图 API 和 控件 之间的关系, 可以类⽐成机器指令和⾼级语⾔之间的关系.

        控件是对画图 API 的进⼀步封装; 画图 API 是控件的底层实现.

绘图 API 核⼼类

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

         绘图 API 的使⽤, ⼀般不会在 QWidget 的构造函数中使⽤, ⽽是要放到 paintEvent 事件中.

  绘制各种形状

        绘制线段

        使用painter.drawLine(x1, y1, x2, y2)可以绘制从点 (x1, y1) 到点 (x2, y2) 的直线。

        绘制矩形

        使用painter.drawRect(x, y, width, height)可以绘制一个矩形,左上角坐标为 (x, y),宽为 width,高为 height

        绘制圆形

        使用painter.drawEllipse(x, y, width, height)可以绘制一个椭圆或者近似圆形,其外接矩形的左上角坐标为 (x, y),宽为 width,高为 height

        绘制文本

        使用painter.drawText(x, y, text)可以在指定的位置 (x, y) 绘制文本 text

        设置画笔

        使用painter.setPen(pen)可以设置画笔的颜色、线条宽度、样式等属性。

        设置画刷

        使用painter.setBrush(brush)可以设置画刷的颜色,用于填充形状的内部。

示例代码:

#include <QtWidgets>class MyWidget : public QWidget
{
public:MyWidget(QWidget *parent = nullptr) : QWidget(parent) {}protected:void paintEvent(QPaintEvent *event) override{Q_UNUSED(event);QPainter painter(this);// 绘制线段painter.setPen(Qt::black);  // 设置画笔颜色为黑色painter.drawLine(20, 20, 200, 20);  // 从 (20, 20) 到 (200, 20) 绘制一条线段// 绘制矩形painter.setPen(Qt::blue);  // 设置画笔颜色为蓝色painter.drawRect(20, 40, 100, 50);  // 绘制一个矩形,左上角坐标 (20, 40),宽高为 100x50// 绘制圆形painter.setPen(Qt::red);  // 设置画笔颜色为红色painter.drawEllipse(20, 100, 80, 80);  // 绘制一个圆形,外接矩形左上角坐标 (20, 100),宽高为 80x80// 绘制文本painter.setPen(Qt::black);  // 设置画笔颜色为黑色painter.setFont(QFont("Arial", 12));  // 设置字体和字号painter.drawText(20, 200, "Hello, Qt!");  // 在 (20, 200) 处绘制文本// 设置画笔和画刷painter.setPen(Qt::black);  // 设置画笔颜色为黑色painter.setBrush(Qt::green);  // 设置画刷颜色为绿色painter.drawRect(20, 220, 100, 50);  // 绘制一个带有绿色填充的矩形,左上角坐标 (20, 220),宽高为 100x50}
};int main(int argc, char *argv[])
{QApplication app(argc, argv);MyWidget widget;widget.resize(300, 300);widget.setWindowTitle("Drawing Shapes in Qt");widget.show();return app.exec();
}

代码结果: 

  绘制图片

        使用QPixmap pixmap(":/images/cat.jpg")加载一个图片,路径可以是文件系统路径或者Qt资源文件路径。

        绘制简单图片

        使用painter.drawPixmap(x, y, pixmap)在指定位置 (x, y) 绘制原始大小的图片。

        缩放图片

        使用pixmap.scaled(width, height, aspectRatioMode)可以缩放图片到指定的宽度和高度,aspectRatioMode参数指定保持长宽比的方式。

        旋转图片

        使用pixmap.transformed(QTransform().rotate(angle))可以旋转图片,angle为旋转的角度。

使用QPixmap实现代码示例:

#include <QtWidgets>class MyWidget : public QWidget
{
public:MyWidget(QWidget *parent = nullptr) : QWidget(parent) {}protected:void paintEvent(QPaintEvent *event) override{Q_UNUSED(event);QPainter painter(this);// 加载图片QPixmap pixmap(":/images/cat.jpg");  // 替换为你自己的图片路径或者资源文件路径// 绘制简单图片painter.drawPixmap(20, 20, pixmap);  // 在 (20, 20) 处绘制原始大小的图片// 缩放图片QPixmap scaledPixmap = pixmap.scaled(200, 150, Qt::KeepAspectRatio);  // 缩放图片到 200x150 大小,保持长宽比painter.drawPixmap(240, 20, scaledPixmap);  // 在 (240, 20) 处绘制缩放后的图片// 旋转图片QPixmap rotatedPixmap = pixmap.transformed(QTransform().rotate(30.0));  // 旋转图片30度painter.drawPixmap(20, 200, rotatedPixmap);  // 在 (20, 200) 处绘制旋转后的图片}
};int main(int argc, char *argv[])
{QApplication app(argc, argv);MyWidget widget;widget.resize(500, 400);widget.setWindowTitle("Pixmap Drawing in Qt");widget.show();return app.exec();
}

代码结果: 

  特殊的画图设备

        前⾯的代码中我们是使⽤ QWidget 作为绘图设备. 在 Qt 中还存在下列三个⽐较特殊的绘图设备. 此处我们也简要介绍.

• QPixmap ⽤于在显⽰器上显⽰图⽚.
• QImage ⽤于对图⽚进⾏像素级修改.
• QPicture ⽤于对 QPainter 的⼀系列操作进⾏存档.

        QPixmap

  • 定义:QPixmap是一个用于处理图像显示的类,它以设备无关的方式存储图像数据,通常用于在屏幕上绘制图像。
  • 特点:QPixmap支持设备无关的图像操作,可以在不同平台上使用相同的接口来处理图像。它可以从文件、内存或绘制操作中创建,并且可以用作GUI界面中的图像资源。
  • 用途:常用于在Qt应用程序中绘制、显示图像,例如在标签、按钮等控件中显示图像。
#include <QApplication>
#include <QLabel>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 创建一个QPixmap对象并加载图片QPixmap pixmap("path/to/image.png");// 创建一个标签并显示图片QLabel label;label.setPixmap(pixmap);label.show();return app.exec();
}

        QImage

  • 定义:QImage是一个用于处理图像数据的类,它提供了对像素级别的直接访问,支持丰富的图像处理和转换功能。
  • 特点:QImage存储像素数据,并提供了对像素级别的访问和编辑。它可以从文件加载图像,也可以通过像素级别的操作进行创建和编辑。
  • 用途:适合需要对图像进行详细处理、转换、编辑的场景,例如图像处理应用、算法实现等。
#include <QApplication>
#include <QImage>
#include <QLabel>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 创建一个QImage对象并加载图片QImage image("path/to/image.png");// 修改图片像素,这里简单地将图片变为灰度for (int y = 0; y < image.height(); ++y) {for (int x = 0; x < image.width(); ++x) {QRgb pixel = image.pixel(x, y);int gray = qGray(pixel);image.setPixel(x, y, qRgb(gray, gray, gray));}}// 创建一个标签并显示图片QLabel label;label.setPixmap(QPixmap::fromImage(image));label.show();return app.exec();
}

        QPicture

  • 定义:QPicture是一个用于记录和重现绘图操作的类,它存储了绘图操作的命令序列而非像素数据。
  • 特点:QPicture可以记录绘制操作(如绘制线条、文本、图形等),并且可以在需要时进行重放。它不直接处理像素级别的图像数据,而是记录绘制操作的历史。
  • 用途:通常用于需要重放绘图命令的场景,例如图形绘制的撤销和重做、打印预览等。
#include <QApplication>
#include <QPainter>
#include <QPicture>
#include <QLabel>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 创建一个QPicture对象并记录绘图操作QPicture picture;QPainter painter;painter.begin(&picture);painter.setPen(Qt::red);painter.drawRect(10, 10, 100, 100);painter.drawLine(20, 20, 80, 80);painter.end();// 创建一个标签并显示QPicture中记录的绘图操作QLabel label;painter.begin(&label);painter.drawPicture(0, 0, picture);painter.end();label.show();return app.exec();
}

总结:

  • QPixmap用于显示和处理图像,提供了简单的设备无关接口。
  • QImage用于直接处理图像数据,支持更多的图像操作和转换。
  • QPicture用于记录和重放绘图命令,适合于需要复杂绘图历史记录和重现的场景。

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

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

相关文章

[Go 微服务] Kratos 使用的简单总结

文章目录 1.Kratos 简介2.传输协议3.日志4.错误处理5.配置管理6.wire 1.Kratos 简介 Kratos并不绑定于特定的基础设施&#xff0c;不限定于某种注册中心&#xff0c;或数据库ORM等&#xff0c;所以您可以十分轻松地将任意库集成进项目里&#xff0c;与Kratos共同运作。 API -&…

Linux内网端口转公网端口映射

由于服务商做安全演练&#xff0c;把原先服务器内网的端口映射到外网端口全都关闭了&#xff0c;每次维护服务器特别麻烦&#xff0c;像数据库查询如果用原生的mysql 去连接&#xff0c;查询返回的结果乱了&#xff0c;非常不方便。 查了服务还是可以正常访问部分外网的&#x…

抖音外卖服务商入驻流程及费用分别是什么?入驻官方平台的难度大吗?

随着抖音关于新增《【到家外卖】内容服务商开放准入公告》的意见征集通知&#xff08;以下简称“通知”&#xff09;的发布&#xff0c;抖音外卖服务商入驻流程及费用逐渐成为众多创业者所关注和热议的话题。不过&#xff0c;就当前的讨论情况来看&#xff0c;这个话题似乎没有…

软件测试中安全测试包含内容及安全测试怎么测

一、软件测试安全测试包含哪些 1. 漏洞扫描 漏洞扫描是软件测试安全测试的基础&#xff0c;它用于检测应用程序和系统中存在的已知漏洞。安全测试工具如AppScan、OWASP ZAP和Nessus等可以对应用程序进行自动化扫描&#xff0c;发现可能存在的漏洞&#xff0c;如跨站点脚本&am…

7.2、指针变量的定义和使用

代码 #include <iostream> using namespace std; #include <string>int main() {//定义指针int a 10;//指针定义语法&#xff1a;数据类型 * 指针变量名int * p;//让指针记录变量a的地址p &a;cout << "a的地址为&#xff1a;" << &am…

MySQL之应用层优化(二)

应用层优化 Web服务器问题 寻找最优并发度 每个Web服务器都有一个最佳并发度——就是说&#xff0c;让进程处理请求尽可能快&#xff0c;并且不超过系统负载的最优的并发连接数。这就是前面说的最大系统容量。进行一个简单的测量和建模&#xff0c;或者只是反复试验&#xf…

nginx SSI(Server Side Include)服务端包含 合并拼装静态内容

一、什么是SSI 在被传送给浏览器之前&#xff0c;服务器会对 HTML 文档进行完全地读取、分析以及修改&#xff0c;使用SSI指令将文本、图片或代码信息包含到网页中。对于整个页面可以拆分成多个模块&#xff0c;通过SSI指令将几个模块拼接成一个完整的页面&#xff0c;当有内容…

【数据库原理】课程笔记

数据库原理 一、数据库系统基础 数据模型的类型 概念数据模型&#xff1a; 概念数据模型也称概念模型或信息模型,是对现实世界中问题域内事务(特性)的描述,是以用户观点实现世界的模型(图形表示)。主要用于描述事物的概念化结构,使数据库的设计人员在设计初期,避开计算机系统及…

ATA-L2水声功率放大器驱动水声换能器的测试研究

随着水声通信技术的发展&#xff0c;水下通信设备也开始逐步走向实用化&#xff0c;为了满足其实际的使用要求&#xff0c;功率放大器的设计需要具有高效率的特性&#xff0c;并能在水下长时间连续可靠的工作。 压电陶瓷换能器主要负责电信号与声信号之间的转换&#xff0c;换能…

应用密码学—(扩展)欧几里得、DES、RSA、SHA-1算法

1. 欧几里得算法 1.1 分析算法的实现原理 欧几里德&#xff08;Euclid&#xff09;算法&#xff0c;也既常说的“辗转相除法”&#xff0c;公式为gcd(m, n) { return gcd(n, m%n); }&#xff0c;对于任意两个正整数m、n&#xff0c;每次求的一个数字r m % n&#xff0c;然后把…

教育场景中的自动化分拣系统!基于大象机器人UltraArm P340机械臂和传送带的实现

引言 今天我们将展示一个高度自动化的模拟场景&#xff0c;展示多个机械臂与传送带协同工作的高效分拣系统。在这个场景中&#xff0c;机械臂通过视觉识别技术对物体进行分类&#xff0c;并通过精确的机械操作将它们放置在指定的位置。这一系统不仅提高了分拣的速度和准确性&am…

PTrade怎么获取KDJ随机指标?想做量化策略怎么申请PTrade量化软件?

get_KDJ - 随机指标 get_KDJ(high, low, close, n9, m13, m23) 使用场景 该函数仅在回测、交易模块可用 接口说明 获取随机指标KDJ指标的计算结果 PTrade是恒生公司开发的一款专业量化软件&#xff0c;部分合作券商可提供&#xff0c;↑↑↑&#xff01; 参数 high&…

什么是分库分表?它有哪些实现类型?

假如你正在使用关系型数据库开发一款健康类系统。业务发展很好&#xff0c;系统有很多活跃的新老用户&#xff0c;这些用户会和平台的医生团队进行交互&#xff0c;每天可能会生成数万甚至数十万级别的业务数据。这样的话&#xff0c;随着数据量越来越大&#xff0c;系统中的某…

被⽹络罪犯利⽤的5⼤ChatGPT越狱提⽰

⾃ChatGPT发布的近18个月以来&#xff0c;⽹络罪犯们已经能够利⽤⽣成式AI进⾏攻击。OpenAI在其内容政策中制定了限制措施&#xff0c;以阻⽌⽣成恶意内容。作为回应&#xff0c;攻击者们创建了⾃⼰的⽣成式AI平台&#xff0c;如 WormGPT和FraudGPT&#xff0c;并且他们还分享了…

IP地址定位中多源数据融合的应用

IP地址定位如今在诸如网络安全、地理信息服务、智能交通等领域发挥着关键作用。然而&#xff0c;传统的基于单一数据源&#xff08;如IP数据库&#xff09;的定位方法往往存在精度有限、可靠性不足等问题。多源数据融合技术的出现为解决这些问题提供了新的思路和方法。今天我们…

石墨烯分散液制备方法众多 应用领域广泛

石墨烯分散液制备方法众多 应用领域广泛 石墨烯分散液指将石墨烯纳米片均匀分散在特定溶剂中制成的溶液。石墨烯分散液具有化学稳定性好、生物相容性好、热稳定性好等优势&#xff0c;未来有望在涂料、纤维制品、电池制造、油墨等领域获得广泛应用。 石墨烯分散液以石墨…

绝区零卡顿严重、延迟高的解决方法提前看

绝区零这款游戏背后是一个错综复杂的架空世界&#xff0c;仿佛一幅波澜壮阔的史诗画卷缓缓展开。在这个世界中&#xff0c;神秘莫测的“空洞”灾害如影随形&#xff0c;给大地带来了无尽的破坏和混沌。经过米哈游团队的精心雕琢&#xff0c;无论是画面UI的细腻呈现&#xff0c;…

灌区量测水管理系统是如何实现灌区节水?

随着全球水资源日益紧张&#xff0c;节水已成为农业生产中不可忽视的一环。在灌区管理中&#xff0c;量测水管理系统以其精准的数据监测和科学的灌溉管理&#xff0c;为实现灌区节水提供了强有力的技术支持。 灌区量测水管理系统是一套集成了自动化监测、数据传输、数据分析和…

Springboot交流论坛网站00304

Springboot交流论坛网站 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了交流论坛网站的开发全过程。通过分析交流论坛网站管理的不足&#xff0c;创建了一个计算机管理交流论坛网站的方案。文章介绍了交流论坛…

elementui中table组件合并行(看就懂)

做一个动态合并的table表格, 如下图 1.首先定义需要合并的字段及合并后的对象 data(){return {mergeFields: [name, amount3],mergeObj: {}} }2.分配合并项函数, data为数据源 //获取合并序号getSpanArr(data []) {this.mergeFields.forEach(key > {// 用来记录合并行的起…