zoukankan      html  css  js  c++  java
  • Qt学习笔记-Widget布局管理

    Qt学习笔记4-Widget布局管理

     
     
     
    以《C++ GUI Programming with Qt 4, Second Edition》为参考

    实例:查找对话框

    包含三个文件,finddialog.h,finddialog.cpp及main.cpp。

    //finddialog.h代码

    #ifndef FINDDIALOG_H
    #define FINDDIALOG_H

    #include <QDialog>

    class QCheckBox;
    class QLabel;
    class QLineEdit;
    class QPushButton;

    class FindDialog : public QDialog
    {
        Q_OBJECT

    public:
        FindDialog(QWidget *parent = 0);

    signals:
        void findNext(const QString &str, Qt::CaseSensitivity cs);
        void findPrevious(const QString &str, Qt::CaseSensitivity cs);

    private slots:
        void findClicked();
        void enableFindButton(const QString &text);

    private:
        QLabel *label;
        QLineEdit *lineEdit;
        QCheckBox *caseCheckBox;
        QCheckBox *backwardCheckBox;
        QPushButton *findButton;
        QPushButton *closeButton;
    };

    #endif

    注释:

    class FindDialog : public QDialog表示继承的对话框,在Qt中QDialog是一个常用到的类。

    Q_OBJECT是一个宏,是信号槽所必须的,在使用信号槽时,在类的开始要使用这个宏,否则在编译时候会出错。

    接下来定义了信号和槽,对于信号和槽以后会详细介绍。

    //finddialog.cpp代码

    #include <QtGui>

    #include "finddialog.h"

    FindDialog::FindDialog(QWidget *parent)


        : QDialog(parent)
    {
        label = new QLabel(tr("Find &what:"));
        lineEdit = new QLineEdit;
        label->setBuddy(lineEdit);

        caseCheckBox = new QCheckBox(tr("Match &case"));
        backwardCheckBox = new QCheckBox(tr("Search &backward"));

        findButton = new QPushButton(tr("&Find"));
        findButton->setDefault(true);
        findButton->setEnabled(false);

        closeButton = new QPushButton(tr("Close"));

        connect(lineEdit, SIGNAL(textChanged(const QString &)),
                this, SLOT(enableFindButton(const QString &)));
        connect(findButton, SIGNAL(clicked()),
                this, SLOT(findClicked()));
        connect(closeButton, SIGNAL(clicked()),
                this, SLOT(close()));

        QHBoxLayout *topLeftLayout = new QHBoxLayout;
        topLeftLayout->addWidget(label);
        topLeftLayout->addWidget(lineEdit);

        QVBoxLayout *leftLayout = new QVBoxLayout;
        leftLayout->addLayout(topLeftLayout);
        leftLayout->addWidget(caseCheckBox);
        leftLayout->addWidget(backwardCheckBox);

        QVBoxLayout *rightLayout = new QVBoxLayout;
        rightLayout->addWidget(findButton);
        rightLayout->addWidget(closeButton);
        rightLayout->addStretch();

        QHBoxLayout *mainLayout = new QHBoxLayout;
        mainLayout->addLayout(leftLayout);
        mainLayout->addLayout(rightLayout);
        setLayout(mainLayout);

        setWindowTitle(tr("Find"));
        setFixedHeight(sizeHint().height());
    }

    void FindDialog::findClicked()
    {
        QString text = lineEdit->text();
        Qt::CaseSensitivity cs =
                caseCheckBox->isChecked() ? Qt::CaseSensitive
                                          : Qt::CaseInsensitive;
        if (backwardCheckBox->isChecked()) {
            emit findPrevious(text, cs);
        } else {
            emit findNext(text, cs);
        }
    }

    void FindDialog::enableFindButton(const QString &text)
    {
        findButton->setEnabled(!text.isEmpty());
    }

    在finddialog.cpp中主要就是实现了信号与槽的关联以及布局管理。这里主要说明一下布局管理。

    Qt提供了在窗口组件上管理子窗口组件的管理方式:

    1.绝对位置方式:通过基类QWidget提供的setGeometry() 设置子窗口组件的大小及其在父窗口的位置。缺点:不能调整子窗口大小,不能随父窗口大小改变而改变,子窗口大小和文本可能会被截断,程序员需要不断计算子窗口大小和位置。

    2.手工布局方式:也是通过基类QWidget提供的setGeometry() 设置子窗口组件的大小及其在父窗口的位置。不过它与第一种不同,它是通过重载QWidget::resizeEvent(QResizeEvent*)函数来实现。当父窗口改变时子窗口会做出相应改变。但是它仍然需要程序员手工计算。

    3.布局管理器方式:这是最好的Qt布局管理方式,它主要提供了4中方式:

    (1)水平布局管理器:QHBoxLayout,按水平方向组织窗口组件

    (2)垂直布局管理器:QVBoxLayout,按垂直方向组织窗口组件

    (3)网格布局管理器:QGridLayout,按二维网格方式组织窗口组件

    (4)栈布局管理器:QStackedLayout,按照类似于栈的方式组织窗口组件,在某一时刻只有一个窗口组件是可见的,Qt没有提供对该布局管理器的支持,但是提供了一个栈部件,QStackedWidget,可以使用它来实现栈布局管理器。

    在上面的例子中,使用其中的两个布局管理器,水平和垂直布局管理器。下面的图是以上代码布局管理后的一个图

    Qt学习笔记4-Widget布局管理 - ugene - 爱在将来时
     对照这个图与上面的代码分析一下是怎么实现这样的布局的。

    QHBoxLayout *topLeftLayout = new QHBoxLayout;
    topLeftLayout->addWidget(label);
    topLeftLayout->addWidget(lineEdit);

    首先创建水平布局,然后再在最上面左边添加两个组件:label,lineEdit

    QVBoxLayout *leftLayout = new QVBoxLayout;
    leftLayout->addLayout(topLeftLayout);
    leftLayout->addWidget(caseCheckBox);
    leftLayout->addWidget(backwardCheckBox);

    然后又创建垂直布局,然后再把上面的水平布局添加到该垂直布局的最上面,接着添加两个组件:caseCheckBox,backwardCheckBox。

    QVBoxLayout *rightLayout = new QVBoxLayout;
    rightLayout->addWidget(findButton);
    rightLayout->addWidget(closeButton);
    rightLayout->addStretch();

    接着创建了一个垂直布局,添加两个组件:findButton,closeButton,之后加入了拉伸系数,也可以叫弹簧,因为就像弹簧一样把这些组件顶起来,可以试试在findButton和closeButton直接加入弹簧看看是什么结果。

    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->addLayout(leftLayout);
    mainLayout->addLayout(rightLayout);
    setLayout(mainLayout);

    最后,又创建了一个水平布局,在这个水平布局中添加了前面创建的后两个布局:水平布局和垂直布局。之后就设置布局管理器,setLayout(),参数是布局管理器名。

    布局管理器就说这么多,后面还会提到。布局管理器在Qt中非常实用。

    下面是该实例的总体类关系图:

    Qt学习笔记4-Widget布局管理 - ugene - 爱在将来时
     可以根据上述代码体会一下。

    最后的是mian代码

    // main.cpp代码

    #include <QApplication>

    #include "finddialog.h"

    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        FindDialog *dialog = new FindDialog;
        dialog->show();
        return app.exec();

  • 相关阅读:
    [hihoCoder] #1093 : 最短路径·三:SPFA算法
    [hihoCoder] #1089 : 最短路径·二:Floyd算法
    [LeetCode] Number of Islands
    PRML5-神经网络(1)
    CUDA2.4-原理之性能优化及浮点运算
    PRML1-引言
    PGM1.1-简介
    AI1.1-人工智能史
    数学-矩阵计算(4)两种布局
    数学-矩阵计算(2)矩阵函数微积分前奏
  • 原文地址:https://www.cnblogs.com/L-H-R-X-hehe/p/3816257.html
Copyright © 2011-2022 走看看