zoukankan      html  css  js  c++  java
  • 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();

    }

  • 相关阅读:
    常见的消息队列中间件介绍
    关系型数据库和非关系型数据库区别、oracle与mysql的区别
    SQL Server 和 Oracle 以及 MySQL 数据库
    Redis,Memcache,MongoDb的特点与区别
    详解布隆过滤器的原理,使用场景和注意事项
    Redis缓存穿透、缓存击穿以及缓存雪崩
    RPC、HTTP、RESTful
    集群,分布式,微服务概念和区别理解
    电脑双屏变单屏后,界面显示问题
    JDK 15已发布,你所要知道的都在这里!
  • 原文地址:https://www.cnblogs.com/bruce1992/p/14311392.html
Copyright © 2011-2022 走看看