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.pswp.cn/diannao/39844.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/39844.shtml
英文地址,請注明出處:http://en.pswp.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…

知識圖譜查詢語言的表示

文章目錄 SPARQL知識圖譜查詢基本構成常見的SPARQL查詢算子語義Markup表示語言SPARQL知識圖譜查詢基本構成 RDF 支持類似數據庫的查詢語言,叫作SPARQL,它提供了查詢RDF 數據的標準語法、處理SPARQL查詢的規則以及結果返回形式。 變量,RDF中的資源,以“?”或者“$”指示;…

【chatgpt】pytorch的全連接層FC

文章目錄 創建全連接層全連接層&#xff08;線性層&#xff09;使用 PyTorch 定義全連接層1. 定義一個全連接層2. 查看層的參數3. 使用全連接層 示例&#xff1a;構建一個簡單的神經網絡總結 打印FC參數輸出解釋完整代碼示例示例輸出總結 線性層的參數和屬性線性層的參數和屬性…

抖音外賣服務商入駐流程及費用分別是什么?入駐官方平臺的難度大嗎?

隨著抖音關于新增《【到家外賣】內容服務商開放準入公告》的意見征集通知&#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…

2024年湖南省各市科小申報時間(科技型中小企業申報流程、條件、好處)新政

湖南省各市科小申報時間流程 一、評價管理 省科技廳牽頭負責科技型中小企業評價工作的組織和監督、實地核查、公示公告、入庫登記及編號撤銷和集中抽查工作&#xff0c;及時處理相關異議、投訴和舉報信息。 各市州科技局負責科技型中小企業評價工作的具體實施&#xff0c;組…

nginx SSI(Server Side Include)服務端包含 合并拼裝靜態內容

一、什么是SSI 在被傳送給瀏覽器之前&#xff0c;服務器會對 HTML 文檔進行完全地讀取、分析以及修改&#xff0c;使用SSI指令將文本、圖片或代碼信息包含到網頁中。對于整個頁面可以拆分成多個模塊&#xff0c;通過SSI指令將幾個模塊拼接成一個完整的頁面&#xff0c;當有內容…

【數據庫原理】課程筆記

數據庫原理 一、數據庫系統基礎 數據模型的類型 概念數據模型&#xff1a; 概念數據模型也稱概念模型或信息模型,是對現實世界中問題域內事務(特性)的描述,是以用戶觀點實現世界的模型(圖形表示)。主要用于描述事物的概念化結構,使數據庫的設計人員在設計初期,避開計算機系統及…

ATA-L2水聲功率放大器驅動水聲換能器的測試研究

隨著水聲通信技術的發展&#xff0c;水下通信設備也開始逐步走向實用化&#xff0c;為了滿足其實際的使用要求&#xff0c;功率放大器的設計需要具有高效率的特性&#xff0c;并能在水下長時間連續可靠的工作。 壓電陶瓷換能器主要負責電信號與聲信號之間的轉換&#xff0c;換能…

mybatis配置返回boolean類型

先大概說明一下ResultMap和ResultType的使用場景 ResultMap適用于復雜的查詢&#xff0c;可以處理多表關聯查詢、嵌套查詢等情況。通過ResultMap&#xff0c;可以更精確地控制查詢結果的映射。ResultType適用于簡單的查詢&#xff0c;而ResultMap適用于復雜的查詢。具體使用哪…

學習整理在php中使用PHPExcel讀取excel表列數大于Z時讀取不到的解決方案

php讀取excel列數大于Z時讀取不到 背景解決方案關鍵代碼 背景 表格數據超過26列&#xff0c; 也就是在Z列之前沒有AA列及以后的情況&#xff0c; 測試一直都沒有問題&#xff0c;超過&#xff0c;就會獲取不到數據了 解決方案 private function getExcelData(){//獲取excel文…

使用Python進行文件屬性修改

哈嘍,大家好,我是木頭左! 在計算機中,文件屬性是指與文件相關的元數據,如創建時間、修改時間、訪問時間等。這些屬性對于管理和組織文件非常重要。Python提供了一些內置的函數和方法,可以方便地修改文件的屬性。本文將介紹如何使用Python進行文件屬性的修改。 1. 獲取文件…

應用密碼學—(擴展)歐幾里得、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;系統中的某…

如何在返利App中進行高效的異常處理與監控

如何在返利App中進行高效的異常處理與監控 大家好&#xff0c;我是微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 在開發返利App過程中&#xff0c;高效的異常處理與監控是確保系統穩定性和用戶體驗的關鍵。本文將深入探討…