Qt中QStackedWidget的實(shí)現(xiàn)示例
一、基本概念
1.1 什么是 QStackedWidget
QStackedWidget 是 Qt 中的一個(gè)容器控件,它可以包含多個(gè)子控件(頁(yè)面),但一次只顯示其中一個(gè)。類似于一疊卡片,只有最上面的卡片可見(jiàn)。
1.2 主要特點(diǎn)
- 多個(gè)頁(yè)面共享同一顯示區(qū)域
- 一次只顯示一個(gè)頁(yè)面
- 可通過(guò)索引或指針切換頁(yè)面
- 常用于實(shí)現(xiàn)標(biāo)簽頁(yè)、向?qū)Ы缑娴?/li>
二、Qt6 中的語(yǔ)法和 API
2.1 基本 API
#include <QStackedWidget> // 創(chuàng)建 QStackedWidget *stackedWidget = new QStackedWidget(parent); // 添加頁(yè)面 int index = stackedWidget->addWidget(widget); int index = stackedWidget->insertWidget(index, widget); // 切換頁(yè)面 stackedWidget->setCurrentIndex(index); // 通過(guò)索引 stackedWidget->setCurrentWidget(widget); // 通過(guò)指針 // 獲取信息 int currentIndex = stackedWidget->currentIndex(); QWidget *currentWidget = stackedWidget->currentWidget(); int count = stackedWidget->count(); QWidget *widget = stackedWidget->widget(index); // 移除頁(yè)面 stackedWidget->removeWidget(widget);
2.2 信號(hào)
// 當(dāng)前頁(yè)面改變時(shí)發(fā)射 void currentChanged(int index); void widgetRemoved(int index);
三、案例
QStackWidget核心
// 創(chuàng)建堆疊布局
m_stackedWidget = new QStackedWidget(this);
QWidget *gridPage = new QWidget();
// 創(chuàng)建詳情頁(yè)
m_detailpage = new detailpage(this);
// 添加到堆疊窗口
m_stackedWidget->addWidget(gridPage);
m_stackedWidget->addWidget(m_detailpage);這里我們可以看到兩個(gè)頁(yè)面都添加到堆疊布局中:
我們可以通過(guò) m_stackedWidget->setCurrentIndex(index);的方式進(jìn)行切換:
例如上面的那個(gè)當(dāng)index=0時(shí)就是gridPage頁(yè)面;當(dāng)index=1時(shí)就是detailpage。
整體代碼
mianwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "detailpage.h"
#include <QMainWindow>
#include <QStackedWidget>
#include <QGridLayout>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void onProductClicked(int index);
void onBackFromDetail();
private:
Ui::MainWindow *ui;
struct ProductInfo
{
QString title;
QString image;
QString details;
};
void setupUI();
void initProducts();
bool eventFilter(QObject *obj, QEvent *event);
QVector<ProductInfo> m_products;
QStackedWidget *m_stackedWidget;
QGridLayout *m_gridLayout;
detailpage *m_detailpage;
};
#endif // MAINWINDOW_Hmainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QLabel>
#include <QMouseEvent>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
setupUI();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::setupUI()
{
resize(800, 600);
// 創(chuàng)建堆疊布局
m_stackedWidget = new QStackedWidget(this);
QWidget *gridPage = new QWidget();
m_gridLayout = new QGridLayout(gridPage);
m_gridLayout->setSpacing(10);
// 創(chuàng)建詳情頁(yè)
m_detailpage = new detailpage(this);
// 添加到堆疊窗口
m_stackedWidget->addWidget(gridPage);
m_stackedWidget->addWidget(m_detailpage);
setCentralWidget(m_stackedWidget);
// 初始化產(chǎn)品數(shù)據(jù)
initProducts();
// 創(chuàng)建產(chǎn)品卡片
for (int i = 0; i < m_products.size(); ++i) {
const ProductInfo &product = m_products[i];
// 創(chuàng)建卡片容器
QWidget *card = new QWidget();
card->setFixedSize(200, 200);
card->setProperty("productIndex", i);
card->installEventFilter(this);
// 卡片內(nèi)部布局
QVBoxLayout *cardLayout = new QVBoxLayout(card);
// 產(chǎn)品圖標(biāo)
QLabel *iconLabel = new QLabel(product.image);
iconLabel->setAlignment(Qt::AlignCenter);
cardLayout->addWidget(iconLabel);
// 產(chǎn)品標(biāo)題
QLabel *titleLabel = new QLabel(product.title);
titleLabel->setAlignment(Qt::AlignCenter);
cardLayout->addWidget(titleLabel);
// 添加到網(wǎng)格布局
int row = i / 3;
int col = i % 3;
m_gridLayout->addWidget(card, row, col, Qt::AlignCenter);
}
// 連接信號(hào)
connect(m_detailpage, &detailpage::backRequest, this, &MainWindow::onBackFromDetail);
}
void MainWindow::initProducts()
{
m_products = {
{
"火災(zāi)預(yù)防",
"??",
"火災(zāi)預(yù)防是消防安全的第一道防線。本產(chǎn)品包含家庭用電安全規(guī)范、廚房用火注意事項(xiàng)等。"
}
};
}
void MainWindow::onProductClicked(int index)
{
if (index >= 0 && index < m_products.size()) {
const ProductInfo &product = m_products[index];
m_detailpage->setProductInfo(product.title, product.image, product.details);
m_stackedWidget->setCurrentIndex(1);
}
}
void MainWindow::onBackFromDetail()
{
m_stackedWidget->setCurrentIndex(0);
}
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::LeftButton) {
QWidget *card = qobject_cast<QWidget*>(obj);
if (card) {
int index = card->property("productIndex").toInt();
onProductClicked(index);
return true;
}
}
}
return QWidget::eventFilter(obj, event);
}detailpage.h
#ifndef DETAILPAGE_H
#define DETAILPAGE_H
#include <QWidget>
#include <QTextEdit>
#include <QPushButton>
class detailpage : public QWidget
{
Q_OBJECT
public:
explicit detailpage(QWidget *parent = nullptr);
void setProductInfo(const QString &title, const QString &image, const QString &details);
signals:
void backRequest();
private slots:
void onBackClicked();
private:
QTextEdit *m_detailsText;
QPushButton *m_backButton;
};
#endif // DETAILPAGE_Hdetailpage.cpp
#include "detailpage.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
detailpage::detailpage(QWidget *parent)
: QWidget{parent}
{
QVBoxLayout *mainLayout = new QVBoxLayout(this);
// 返回按鈕
m_backButton = new QPushButton("返回");
connect(m_backButton, &QPushButton::clicked, this, &detailpage::onBackClicked);
// 詳細(xì)信息顯示
m_detailsText = new QTextEdit();
m_detailsText->setReadOnly(true);
mainLayout->addWidget(m_backButton);
mainLayout->addWidget(m_detailsText);
}
void detailpage::setProductInfo(const QString &title, const QString &image, const QString &details)
{
QString formattedDetails = QString("<h2>%1</h2><p>%2</p>").arg(title, details);
m_detailsText->setHtml(formattedDetails);
}
void detailpage::onBackClicked()
{
emit backRequest();
}四、效果
第一個(gè)界面

點(diǎn)擊圖標(biāo)后跳轉(zhuǎn)到第二個(gè)界面

到此這篇關(guān)于Qt中QStackedWidget的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Qt QStackedWidget 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用C++實(shí)現(xiàn)一個(gè)高效的線程池
在多線程編程中,線程池是一種常見(jiàn)且高效的設(shè)計(jì)模式,本文將詳細(xì)介紹如何使用C++實(shí)現(xiàn)一個(gè)線程池,并解析相關(guān)代碼實(shí)現(xiàn)細(xì)節(jié),需要的小伙伴可以參考下2024-12-12
C++11, 14, 17對(duì)tuple元素的訪問(wèn)詳情
這篇文章主要介紹了C++11, 14, 17對(duì)tuple元素的訪問(wèn)詳情,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
C++實(shí)踐數(shù)組作數(shù)據(jù)成員的參考
今天小編就為大家分享一篇關(guān)于C++實(shí)踐數(shù)組作數(shù)據(jù)成員的參考,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02
vector list map 遍歷刪除制定元素 防止迭代器失效的實(shí)例
下面小編就為大家?guī)?lái)一篇vector list map 遍歷刪除制定元素 防止迭代器失效的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12
C++?中?std::map的insert函數(shù)使用案例
C++中std::map::insert用于安全插入鍵值對(duì),檢查鍵是否存在避免覆蓋,返回迭代器和布爾值,支持多種重載形式,鍵唯一,時(shí)間復(fù)雜度O(logn),需注意返回值判斷,本文給大家介紹C++?中?std::map的insert函數(shù)使用案例,感興趣的朋友一起看看吧2025-08-08
C++圖形界面開(kāi)發(fā)Qt教程:嵌套圓環(huán)示例
這篇文章主要介紹了C++實(shí)現(xiàn)圖形界面開(kāi)發(fā)Qt教程,涉及坐標(biāo)函數(shù)的應(yīng)用及圖形界面程序設(shè)計(jì),需要的朋友可以參考下,希望能給你帶來(lái)幫助2021-08-08

