以《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,可以使用它来实现栈布局管理器。

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

对照这个图与上面的代码分析一下是怎么实现这样的布局的。

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中非常实用。

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

可以根据上述代码体会一下。

最后的是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();

Qt学习笔记-Widget布局管理的更多相关文章

  1. Android学习笔记(10).布局管理器

    布局管理器的几个类都是ViewGroup派生的,用于管理组件的分布和大小,使用布局管理器能够非常好地解决屏幕适配问题. 布局管理器本身也是一个UI组件,布局管理器能够相互嵌套使用,以下是布局管理器的类 ...

  2. qt学习笔记(五) QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果

    应大家的要求,还是把完整的project文件贴出来,大家省点事:http://www.kuaipan.cn/file/id_48923272389086450.htm 先看看执行效果,我用的群创7寸屏 ...

  3. QT学习笔记(一)——Helloworld

    QT学习笔记(一)--Helloworld 一.调试的基本方法: Log调试法 --在代码中加入一定的打印语句 --打印程序状态和关键变量的值 断点调试法: --在开发环境中的对应代码行加上断点 -- ...

  4. Linux内核学习笔记-2.进程管理

    原创文章,转载请注明:Linux内核学习笔记-2.进程管理) By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...

  5. linux kernel学习笔记-5内存管理_转

    void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...

  6. Linux学习笔记(五) 账号管理

    1.用户与组账号 用户账号:包括实际人员和逻辑性对象(例如应用程序执行特定工作的账号) 每一个用户账号包含一个唯一的用户 ID 和组 ID 标准用户是系统安装过程中自动创建的用户账号,其中除 root ...

  7. Linux学习笔记(六) 进程管理

    1.进程基础 当输入一个命令时,shell 会同时启动一个进程,这种任务与进程分离的方式是 Linux 系统上重要的概念 每个执行的任务都称为进程,在每个进程启动时,系统都会给它指定一个唯一的 ID, ...

  8. PyQt(Python+Qt)学习随笔:布局控件layout的layoutSizeConstraint属性不起作用的问题解决办法

    在<PyQt(Python+Qt)学习随笔:布局控件layout的layoutSizeConstraint属性>中介绍layout的layoutSizeConstraint属性后,反复测试 ...

  9. XV6学习笔记(2) :内存管理

    XV6学习笔记(2) :内存管理 在学习笔记1中,完成了对于pc启动和加载的过程.目前已经可以开始在c语言代码中运行了,而当前已经开启了分页模式,不过是两个4mb的大的内存页,而没有开启小的内存页.接 ...

随机推荐

  1. Git+Jenkins配置

    一.新建任务 admin账户登陆jenkins,点击新建按钮-> 选择构建一个自由风格的软件项目,item name 随便输入一个自己认为有意义的名字,点击OK 二.源码管理 源码管理-> ...

  2. 转]@SuppressWarnings 详解

    转自:http://gladto.iteye.com/blog/728634 背景知识:        从JDK5开始提供名为Annotation(注释)的功能,它被定义为JSR-175规范.注释是以 ...

  3. Monkey测试:Monkey的简单使用

    Monkey是Android SDK提供的一个命令行工具,可以简单方便的发送伪随机的用户事件流,对Android APP做压力(稳定性)测试.主要是为了测试app是否存在无响应和崩溃的情况. 一.环境 ...

  4. Could not load type 'System.Runtime.CompilerServices.ExtensionAttribute' from assembly 'mscorlib 的一种情形

    没有引用任何.net 4.5的东西,也没有引用 Newtonsoft.dll,原因是引用了微软的tlb类型库,引用方法如 https://www.cnblogs.com/nanfei/p/108798 ...

  5. vimiumC的下载、配置与节点个性化

    vimium是chrome的一款扩展程序,正如其名:vim+chromium,它能让你在浏览网页时双手不离开键盘,是提上网高效率的神器. 最近在使用中,非常便捷高效,但关于节点的个性化资料比较少,自己 ...

  6. 【Airtest】Airtest中swipe方法兼容不同分辨率的解决方法

    使用Airtest中swipe方法由于不同分辨率的手机上滑动的坐标位置不同,所以想要兼容所有的手机,仅仅靠固定坐标就会出现问题 想要兼容所有的手机,可以按照如下思路进行 1.首先获取手机的分辨率,可以 ...

  7. Python中文件读写之 w+ 与 r+ 到底有啥区别?

    其实r 是只读,只能读不能写,这是很明确的,但是r+是可读写,变成r+后还没太明白到底加了什么,还是照样写不了,有没有这样的体验呢,如下代码,只读时 f = open("test.txt&q ...

  8. 从零构建vue项目(三)--vue常用插件

    一.直接拉取的模板中,package.json如下: { "name": "vuecli2-test", "version": " ...

  9. 有序无序Ul->Li Ol->Li菜单,默认点击当前弹出下拉,再次点击收起下拉菜单(变形2 ---修饰)

    从上面可以看出,两个问题,第一:下拉出现的太快太突然,第二:再点击下一个下拉菜单的时候,上一个不会闭合,针对这两个问题,接下来会一 一解决. 解决下拉太快: js中有个jquery效果,有一个效果是j ...

  10. nodejs版实现properties后缀文件解析

    1.propertiesParser.js let readline = require('readline'); let fs = require('fs'); // properties文件路径 ...