• 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();

    }

  • 相关阅读:
    中国历史朝代公元对照简表
    [Solved] DashBoard – Excel Service: The data sources may be unreachable, may not be responding, or may have denied you access.
    Delete/Remove Project from TFS 2010
    Sharepoint site showing system account instead of my username on the top right corner.
    你的成功在于你每天养成的习惯
    Internet Information Services is running in 32bit emulation mode. Correct the issue listed above and rerun setup.
    Prepare to back up and restore a farm (Office SharePoint Server 2007)
    Word中字号与磅值的对应关系
    How to: Change the Frequency for Refreshing the Data Warehouse for Team System
    UI Automation in WPF/Silverlight
  • 原文地址:https://www.cnblogs.com/bruce1992/p/14311392.html
Copyright © 2020-2023  润新知