Qt學習筆記(2)-利用StackWidget實現選項卡式頁面


 學習筆記第二篇,利用Qt實現選項卡式的頁面,效果如圖1.1-圖1.3所示。程序實現的功能是通過點擊狀態欄實現不同頁面的切換,實際上Qt中自帶有Tab選項卡式的控件,本文利用StackWidge實現類似的頁面切換功能。本文的開發思路以及頁面代碼參考了陸文周主編的《Qt5開發及實例(第3版)》(中國工信出版社)。

 

 

 

1.1 基本信息界面

 

 

 

1.2 聯系方式界面

 

 

 

1.3 詳細資料界面

        本文軟件的框架如圖1.4所示,下面從最下層的內容開始介紹。

 

 

 

1.4 軟件開發框架

        1、底層頁面的構建

        最底層的頁面分為三個類,基本信息(BaseInfo)類,聯系方式(Contact)類以及詳細資料(Detail)類,三個類均繼承自QWidget類。

        (1)Class BaseInfo

        baseinfo.h

#ifndef BASEINFO_H

#define BASEINFO_H

#include <QtCore/qglobal.h>

#if QT_VERSION >= 0x050000

#include <QtWidgets/QWidget>

#else

#include <QtGui/QWidget>

#endif

#include <QLabel>

#include <QLineEdit>

#include <QComboBox>

#include <QTextEdit>

#include <QGridLayout>

#include <QPushButton>

#include <QHBoxLayout>

#include <QVBoxLayout>

#include <QPixmap>

class BaseInfo : public QWidget

{

    Q_OBJECT

public:

    explicit BaseInfo(QWidget *parent = nullptr);

signals:

public slots:

private:

    //左側

    QLabel *UserNameLabel;                      //用戶名

    QLabel *NameLabel;                          //姓名

    QLabel *SexLabel;                           //性別

    QLabel *DepartmentLabel;                    //部門

    QLabel *AgeLabel;                           //年齡

    QLabel *OtherLabel;                         //備注

    QLineEdit *UserNameLineEdit;

    QLineEdit *NameLineEdit;

    QComboBox *SexCombox;

    QTextEdit *DepartmentTextEdit;

    QLineEdit *AgeLineEdit;

    QGridLayout *LeftLayout;

    //右側

    QLabel *HeadLabel;                          //右上角部分,頭像

    QLabel *HeadIconLabel;                      //頭像圖標

    QPushButton *UpdateHeadBtn;                 //更新按鈕

    QHBoxLayout *TopRightLayout;                //個人說明

    QLabel *IntroductionLabel;

    QTextEdit *IntroductionTextEdit;

    QVBoxLayout *RightLayout;

};

#endif // BASEINFO_H

        baseinfo.cpp

#include "baseinfo.h"

BaseInfo::BaseInfo(QWidget *parent) : QWidget(parent)

{

    //*****左側*****

    UserNameLabel = new QLabel(tr("用戶名:"));

    UserNameLineEdit = new QLineEdit;

    NameLabel = new QLabel(tr("姓名:"));

    NameLineEdit = new QLineEdit;

    SexLabel = new QLabel(tr("性別:"));

    SexCombox = new QComboBox;

    SexCombox->addItem(tr("男"));

    SexCombox->addItem(tr("女"));

    DepartmentLabel = new QLabel(tr("部門:"));

    DepartmentTextEdit = new QTextEdit;

    AgeLabel = new QLabel(tr("年齡:"));

    AgeLineEdit = new QLineEdit;

    OtherLabel = new QLabel(tr("備注:"));

    OtherLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);

    //左側布局

    LeftLayout = new QGridLayout();

    LeftLayout->addWidget(UserNameLabel, 0, 0);

    LeftLayout->addWidget(UserNameLineEdit, 0, 1);

    LeftLayout->addWidget(NameLabel, 1, 0);

    LeftLayout->addWidget(NameLineEdit, 1, 1);

    LeftLayout->addWidget(SexLabel, 2, 0);

    LeftLayout->addWidget(SexCombox, 2, 1);

    LeftLayout->addWidget(DepartmentLabel, 3, 0);

    LeftLayout->addWidget(DepartmentTextEdit, 3, 1);

    LeftLayout->addWidget(AgeLabel, 4, 0);

    LeftLayout->addWidget(AgeLineEdit, 4, 1);

    LeftLayout->addWidget(OtherLabel, 5, 0, 1, 2);

    LeftLayout->setColumnStretch(0, 1);

    LeftLayout->setColumnStretch(1, 3);

    //*****右側*****

    //右上方

    HeadLabel = new QLabel(tr("頭像:"));

    HeadIconLabel = new QLabel;

    QPixmap icon("123.png");

    HeadIconLabel->setPixmap(icon);

    HeadIconLabel->resize(20, 20);

    UpdateHeadBtn  = new QPushButton(tr("更新"));

    //右上方布局

    TopRightLayout = new QHBoxLayout;

    TopRightLayout->setSpacing(20);

    TopRightLayout->addWidget(HeadLabel);

    TopRightLayout->addWidget(HeadIconLabel);

    //右下方

    IntroductionLabel = new QLabel(tr("個人說明:"));

    IntroductionTextEdit = new QTextEdit;

    //右下方布局

    RightLayout = new QVBoxLayout();

    RightLayout->setMargin(10);

    RightLayout->addLayout(TopRightLayout);

    RightLayout->addWidget(IntroductionLabel);

    RightLayout->addWidget(IntroductionTextEdit);

    //總布局

    QGridLayout *mainLayout = new QGridLayout(this);

    mainLayout->setMargin(15);

    mainLayout->setSpacing(10);

    mainLayout->addLayout(LeftLayout, 0, 0);

    mainLayout->addLayout(RightLayout, 0, 1);

    //mainLayout->setSizeConstraint(QLayout::SetFixedSize);

}

        (2)Class Contact

        contact.h

#ifndef CONTACT_H

#define CONTACT_H

#include <QtCore/qglobal.h>

#if QT_VERSION >= 0x050000

#include <QtWidgets/QWidget>

#else

#include <QtGui/QWidget>

#endif

#include <QLabel>

#include <QGridLayout>

#include <QLineEdit>

#include <QCheckBox>

class Contact : public QWidget

{

    Q_OBJECT

public:

    explicit Contact(QWidget *parent = nullptr);

signals:

public slots:

private:

    QLabel *EmailLabel;

    QLineEdit *EmailLineEdit;

    QLabel *AddrLabel;

    QLineEdit *AddrLineEdit;

    QLabel *CodeLabel;

    QLineEdit *CodeLineEdit;

    QLabel *MoviTelLabel;

    QLineEdit *MoviTelLineEdit;

    QCheckBox *MoviTelCheckBox;

    QLabel *ProTelLabel;

    QLineEdit *ProTelLineEdit;

    QGridLayout *mainLayout;

};

#endif // CONTACT_H

        contact.cpp

#include "contact.h"

Contact::Contact(QWidget *parent) : QWidget(parent)

{

    EmailLabel = new QLabel(tr("電子郵件:"));

    EmailLineEdit = new QLineEdit;

    AddrLabel = new QLabel(tr("聯系地址:"));

    AddrLineEdit = new QLineEdit;

    CodeLabel = new QLabel(tr("郵政編碼:"));

    CodeLineEdit = new QLineEdit;

    MoviTelLabel = new QLabel(tr("移動電話:"));

    MoviTelLineEdit = new QLineEdit;

    MoviTelCheckBox = new QCheckBox(tr("接收留言"));

    ProTelLabel = new QLabel(tr("辦公電話:"));

    ProTelLineEdit = new QLineEdit;

    mainLayout = new QGridLayout(this);

    mainLayout->setMargin(15);

    mainLayout->setSpacing(10);

    mainLayout->addWidget(EmailLabel, 0, 0);

    mainLayout->addWidget(EmailLineEdit, 0, 1);

    mainLayout->addWidget(AddrLabel, 1, 0);

    mainLayout->addWidget(AddrLineEdit, 1, 1);

    mainLayout->addWidget(CodeLabel, 2, 0);

    mainLayout->addWidget(CodeLineEdit, 2, 1);

    mainLayout->addWidget(MoviTelLabel, 3, 0);

    mainLayout->addWidget(MoviTelLineEdit, 3, 1);

    mainLayout->addWidget(MoviTelCheckBox, 3, 2);

    mainLayout->addWidget(ProTelLabel, 4, 0);

    mainLayout->addWidget(ProTelLineEdit, 4, 1);

    mainLayout->setSizeConstraint(QLayout::SetFixedSize);

}

 

        (3)Class Detail

        detail.h

#ifndef DETAIL_H

#define DETAIL_H

#include <QtCore/qglobal.h>

#if QT_VERSION >= 0x050000

#include <QtWidgets/QWidget>

#else

#include <QtGui/QWidget>

#endif

#include <QLabel>

#include <QComboBox>

#include <QLineEdit>

#include <QTextEdit>

#include <QGridLayout>

class Detail : public QWidget

{

    Q_OBJECT

public:

    explicit Detail(QWidget *parent = nullptr);

signals:

public slots:

private:

    QLabel *NationalLabel;

    QComboBox *NationalComboBox;

    QLabel *ProvinceLabel;

    QComboBox *ProvinceComboBox;

    QLabel *CityLabel;

    QLineEdit *CityLineEdit;

    QLabel *IntroductLabel;

    QTextEdit *IntroductTextEdit;

    QGridLayout *mainLayout;

};

#endif // DETAIL_H

        detail.cpp

#include "detail.h"

Detail::Detail(QWidget *parent) : QWidget(parent)

{

    NationalLabel = new QLabel(tr("國家/地址:"));

    NationalComboBox = new QComboBox;

    NationalComboBox->insertItem(0, tr("中國"));

    NationalComboBox->insertItem(1, tr("美國"));

    NationalComboBox->insertItem(2, tr("英國"));

    ProvinceLabel = new QLabel(tr("省份:"));

    ProvinceComboBox = new QComboBox;

    ProvinceComboBox->insertItem(0, tr("江蘇省"));

    ProvinceComboBox->insertItem(1, tr("山東省"));

    ProvinceComboBox->insertItem(2, tr("浙江省"));

    CityLabel = new QLabel(tr("城市:"));

    CityLineEdit = new QLineEdit;

    IntroductLabel = new QLabel(tr("個人說明:"));

    IntroductTextEdit = new QTextEdit;

    mainLayout = new QGridLayout(this);

    mainLayout->setMargin(15);

    mainLayout->setSpacing(10);

    mainLayout->addWidget(NationalLabel, 0, 0);

    mainLayout->addWidget(NationalComboBox, 0, 1);

    mainLayout->addWidget(ProvinceLabel, 1, 0);

    mainLayout->addWidget(ProvinceComboBox, 1, 1);

    mainLayout->addWidget(CityLabel, 2, 0);

    mainLayout->addWidget(CityLineEdit, 2, 1);

    mainLayout->addWidget(IntroductLabel, 3, 0);

    mainLayout->addWidget(IntroductTextEdit, 3, 1);

}

 

        2、將底層頁面放在QStackWidget中

        新建一個Content類,繼承自QFrame。在Content類中,創建一個QStackWidget對象,然后將上述三個頁面插入到此對象中。

        content.h

#ifndef CONTENT_H

#define CONTENT_H

#include <QtCore/qglobal.h>

#if QT_VERSION >= 0x050000

#include <QtWidgets/QWidget>

#else

#include <QtGui/QWidget>

#endif

#include <QFrame>

#include <QStackedWidget>

#include <QGridLayout>

#include "baseinfo.h"

#include "contact.h"

#include "detail.h"

class Content : public QFrame

{

    Q_OBJECT

public:

    explicit Content(QWidget *parent = nullptr);

    QStackedWidget *stack;

    BaseInfo *baseInfo;

    Contact *contact;

    Detail *detail;

signals:

public slots:

private:

    QGridLayout *mainLayout;

};

#endif // CONTENT_H

 

        content.cpp

        這里用了一個QGridLayou布局,布局中只有一個QStackWidget。如果去掉此布局,則在主界面中的Stack頁面無法隨主界面變化,只能保持同一個尺寸,所以這里有必要加一個布局。

#include "content.h"

Content::Content(QWidget *parent) : QFrame(parent)

{

    stack = new QStackedWidget(this);                           //創建一個堆棧窗口對象

    stack->setFrameStyle(QFrame::Panel | QFrame::Raised);       //窗口的顯示風格

    //插入頁面

    baseInfo = new BaseInfo();

    contact = new Contact();

    detail = new Detail();

    stack->addWidget(baseInfo);

    stack->addWidget(contact);

    stack->addWidget(detail);

    mainLayout = new QGridLayout(this);

    mainLayout->setMargin(2);

    mainLayout->addWidget(stack, 0, 0);

}

 

        3、主界面的實現

        這里的主界面不是指main函數,而是指QMainWindow,主界面的類為MainStack繼承自QMainWindow。在主界面上主要實現的功能是狀態欄和Stack界面的顯示以及它們之間的連接。

        mainstack.h

#ifndef MAINSTACK_H

#define MAINSTACK_H

#include <QMainWindow>

#include <QToolBar>

#include <QAction>

#include <QGridLayout>

#include "content.h"

class MainStack : public QMainWindow

{

    Q_OBJECT

public:

    MainStack(QWidget *parent = 0);

    ~MainStack();

    Content *content;

    QGridLayout *mainLayout;

    void createAction();                                //動作處理函數

    void createToolBar();                               //創建工具欄

private:

    QToolBar *stackTool;                                //工具欄

    QAction *openStack[3];

private slots:

    void openBaseInfo();                                //點擊狀態欄的槽函數

    void openContact();

    void openDtail();

};

#endif // MAINSTACK_H

 

        mainstack.cpp

        主界面的中心部件就一個,就不加布局了,所有的布局都加在上一步的QFrame中。

#include "mainstack.h"

MainStack::MainStack(QWidget *parent)

    : QMainWindow(parent)

{

    setWindowTitle(tr("主界面"));

    setMinimumSize(800, 480);

    createAction();

    createToolBar();

    content = new Content(this);

    setCentralWidget(content);                              //將stack窗口設置為中心部件

    //mainLayout = new QGridLayout(this);

    //mainLayout->setMargin(15);

    //mainLayout->setSpacing(10);

    //mainLayout->addWidget(stackTool, 0, 0);

    //mainLayout->addWidget(content, 1, 0);

}

MainStack::~MainStack()

{

}

//Action動作

void MainStack::createAction()

{

    //轉到第一個界面

    openStack[0] = new QAction(tr("基本信息"), this);

    openStack[0]->setShortcut(tr("Ctrl+Q"));

    openStack[0]->setStatusTip(tr("界面1"));

    connect(openStack[0], SIGNAL(triggered(bool)), this, SLOT(openBaseInfo()));

    //轉到第二個界面

    openStack[1] = new QAction(tr("聯系方式"), this);

    openStack[1]->setShortcut(tr("Ctrl+W"));

    openStack[1]->setStatusTip(tr("界面2"));

    connect(openStack[1], SIGNAL(triggered(bool)), this, SLOT(openContact()));

    //轉到第三個界面

    openStack[2] = new QAction(tr("詳細資料"), this);

    openStack[2]->setShortcut(tr("Ctrl+E"));

    openStack[2]->setStatusTip(tr("界面3"));

    connect(openStack[2], SIGNAL(triggered(bool)), this, SLOT(openDtail()));

}

//創建工具欄

void MainStack::createToolBar()

{

    stackTool = addToolBar("工具欄");

    stackTool->addAction(openStack[0]);

    stackTool->addAction(openStack[1]);

    stackTool->addAction(openStack[2]);

}

//轉到界面1槽函數

void MainStack::openBaseInfo()

{

    this->content->stack->setCurrentIndex(0);

}

//轉到界面2槽函數

void MainStack::openContact()

{

    this->content->stack->setCurrentIndex(1);

}

//轉到界面3槽函數

void MainStack::openDtail()

{

    this->content->stack->setCurrentIndex(2);

}

 

        4、main函數

        main函數就是顯示主界面。

#include "mainstack.h"

#include <QApplication>

int main(int argc, char *argv[])

{

    QApplication a(argc, argv);

    MainStack w;

    w.show();

    return a.exec();

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM