Qt——升级系列(Level Eight):界面优化
目录
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);
// 创建一个父级 QWidget
QWidget 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);
// 创建一个父级 QWidget
QWidget 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);
// 创建一个父级 QWidget
QWidget 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);
// 创建一个父级 QWidget
QWidget 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);
// 创建一个父级 QWidget
QWidget 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);
// 创建一个父级 QWidget
QWidget 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);
// 创建一个父级 QWidget
QWidget 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用于记录和重放绘图命令,适合于需要复杂绘图历史记录和重现的场景。
原文地址:https://blog.csdn.net/weixin_66330442/article/details/140147532
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!