1.4 窗口部件的布局

Qt第一章的最后一个内容是部件的布局。

书中的例子用到了一个QHBoxLayout类

这个类能够将放置在布局内的控件自动调整大小和位置,我们不需要手动去调整,比较方便。

第10行:创建一个QWidget对象

QWidget是所有用户界面对象的基类。在这里将会用作其它部件的父对象,在这之上显示相应的控件。也就是说它将作为程序的主窗口。

第11行:设置窗口标题

字面意思上看也的确是设置窗口的标题。

第13行:创建一个QSpinBox对象

用到的函数:QSpinBox::QSpinBox ( QWidget * parent = 0 )

函数的说明:构造一个微调框,默认最小值为0,最大值值为99,初始值为0。

第14行:创建一个QSlider对象

用到的函数:QSlider::QSlider ( Qt::Orientation orientation, QWidget * parent = 0 )

函数的说明:构造一个滑块,并指定滑块方向,Qt::Vertical为垂直方向,Qt::Horizontal为水平方向。

第15~16行:设置有效范围

QSpinBox用到的函数:void QSpinBox::setRange ( intminimum, intmaximum )

QSlider用到的函数:void QAbstractSlider::setRange ( intmin, intmax )

函数的说明:设置微调框和滑块的有效范围,设置完成之后,在实际使用中是不会超过这个范围的,微调框自己手动输入一个非法值也不会被正常输入,这也确保了数值的有效性。

第18~21行:设置信号和槽的连接

QSpinBox和QSlider都拥有一个valueChanged(int)信号,表明当数值发生改变时会发射valueChanged信号。

同时它们也都拥有一个setValue(int)槽。

将QSpinBox的valueChanged信号和QSlider的setValue槽连接之后,当QSpinBox的数值发生改变,QSlider的值也将随之改变。

同理,就可以理解另外一个连接会发生的事情了。

另外,这里可能有一个疑问:微调框的值发生改变,它会调用滑块的setValue来设置滑块的值,这样一来滑块的值也发生改变,滑块也会调用微调框的setValue来设置微调框……如此反复,似乎感觉这样子会出现死循环…?

也不知道是不是我初学的关系,不知道其它人会不会呢?我学到这里的时候就有这个疑问了。后来书中也解释过了,并不会出现这种死循环的局面。

所以,需要知道的是对象何时会发射信号,它是有条件的。微调框发射valueChanged信号的条件是:当数值已经改变

假如数值改变了,它会发射信号,由滑块响应并调用setValue槽来改变自身的值,这时它的值"改变了",但是这里的改变只是"替换"成微调框新的值。

如果这个新的值与滑块原本已有的值是一样的,这就不叫改变了。所以滑块的值保持原样,并不符合数值已经改变这个条件,不会再次发射信号。

一个疑问就这样解开了,它不会造成死循环。

第22行:设置QSpinBox的值

由于已经将信号和槽进行连接了,所以在连接之后进行设置值的话,就会发射信号,相应地会有槽在执行,把QSlider的值设置为和QSpinBox一样的数值。

第24行:创建一个QHBoxLayout对象

用到的函数:QHBoxLayout::QHBoxLayout ()

函数的说明:创建一个水平布局管理器,管理各个控件位置和大小。

第25~26行:将部件添加到水平布局对象中

用到的函数:void QBoxLayout::addWidget ( QWidget * widget, intstretch = 0, Qt::Alignmentalignment = 0 )

函数的说明:将部件添加到布局中,并调整布局内各个控件的大小与位置。

第27行:在主窗口上设置布局管理器

用到的函数:void QWidget::setLayout ( QLayout * layout )

函数的说明:设置布局管理器为这个部件的布局。

最后自然就是将主窗口show()出来了

无论怎样调整窗口的宽度,微调框和滑块都会自动调整大小,的确是个很方便的东西。

接下来比较详细讲的就是布局管理器了:

布局管理器就是一个能够对其所负责窗口部件的尺寸大小和位置进行设置的对象。

Qt中有三个主要的布局管理器类:

QHBoxLayout:在水平方向上排列窗口部件,从左到右。头文件<QHBoxLayout>。

QVBoxLayout:在竖直方向上排列窗口部件,从上到下。头文件<QVBoxLayout>。

QGridLayout:把各个窗口部件排列在一个网格中。头文件<QGridLayout>。

QHBoxLayout,水平布局管理器,就是这样子:

QVBoxLayout,竖直布局管理器,就是这样子:

QGridLayout,网格布局管理器,就是这样子:

用到的函数:void QGridLayout::addWidget ( QWidget * widget, introw, intcolumn, Qt::Alignmentalignment = 0 )

函数的说明:widget指定要添加到布局管理器的对象。row和column为对象放置的位置。

QGridLayout将各个部件都添加到网格中,就像是表格,可以指定部件放在表格的哪一行哪一列。这也是一样的。

这三种布局管理器可以嵌套,可以做出一个很好看的布局。

结合C++的知识与之前所学过的Qt知识,我来随便弄一个界面吧~

#include <QApplication>
#include <QPushButton>
#include <QLineEdit>
#include <QSlider>
#include <QSpinBox>
#include <QLabel>

#include <QLayout>
// 包含了<QLayout>就可以不用再包含以下3个头文件了
/*
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
*/

enum LAYOUT_TYPE
{
	layout_H,	// QHBoxLayout
	layout_V,	// QVBoxLayout
	layout_G	// QGridLayout
};

QLayout * getLayout(LAYOUT_TYPE type);

int main(int argc, char * argv[])
{
	QApplication app(argc, argv);

	QWidget * window = new QWidget;
	window->setWindowTitle("Hello Qt!");

	/***************** 设置顶部菜单选项 ******************/
	QHBoxLayout * Top = (QHBoxLayout *)getLayout(layout_H);

	QPushButton * btn_Menu1 = new QPushButton("Start");
	QPushButton * btn_Menu2 = new QPushButton("Online");
	QPushButton * btn_Menu3 = new QPushButton("Setting");
	QPushButton * btn_Menu4 = new QPushButton("Exit");

	Top->addWidget(btn_Menu1);
	Top->addWidget(btn_Menu2);
	Top->addWidget(btn_Menu3);
	Top->addWidget(btn_Menu4);

	/***************** 设置中部左边部件 ******************/
	QVBoxLayout * midLeft = (QVBoxLayout *)getLayout(layout_V);

	QHBoxLayout * midLeftLayout1 = (QHBoxLayout *)getLayout(layout_H);
	QLabel * tip1 = new QLabel("Sound Volume");
	// 可以手动设置QSlider的方向,Horizontal是水平,Vertical是垂直
	QSlider * slider1 = new QSlider(Qt::Horizontal);
	slider1->setRange(0, 100);
	slider1->setValue(50);
	midLeftLayout1->addWidget(tip1);
	midLeftLayout1->addWidget(slider1);

	QHBoxLayout * midLeftLayout2 = (QHBoxLayout *)getLayout(layout_H);
	QLabel * tip2 = new QLabel("Sound Effect ");
	QSlider * slider2 = new QSlider(Qt::Horizontal);
	slider2->setRange(0, 100);
	slider2->setValue(50);
	midLeftLayout2->addWidget(tip2);
	midLeftLayout2->addWidget(slider2);

	midLeft->addLayout(midLeftLayout1);
	midLeft->addLayout(midLeftLayout2);

	/***************** 设置中部右边部件 ******************/
	QVBoxLayout * midRight = (QVBoxLayout *)getLayout(layout_V);

	QHBoxLayout * midRightLayout1 = (QHBoxLayout *)getLayout(layout_H);
	QLabel * tip3 = new QLabel("Game Levels");
	QSpinBox * spinBox = new QSpinBox();
	spinBox->setRange(1, 10);
	spinBox->setValue(1);
	midRightLayout1->addWidget(tip3);
	midRightLayout1->addWidget(spinBox);

	QHBoxLayout * midRightLayout2 = (QHBoxLayout *)getLayout(layout_H);
	QLabel * tip4 = new QLabel("Player Name");
	QLineEdit * Edit = new QLineEdit();
	midRightLayout2->addWidget(tip4);
	midRightLayout2->addWidget(Edit);

	midRight->addLayout(midRightLayout1);
	midRight->addLayout(midRightLayout2);

	// 将中部左右边的布局管理器添加到中部主布局管理器中
	QHBoxLayout * Mid = (QHBoxLayout *)getLayout(layout_H);
	Mid->addLayout(midLeft);
	Mid->addLayout(midRight);

	/***************** 设置底部部件 ******************/
	QHBoxLayout * Bottom = (QHBoxLayout *)getLayout(layout_H);

	QLabel * lab = new QLabel("All right reserved.");

	// addStretch()用于添加分隔符,用于占位
	// 就是已有的部件大小已确定为最佳的情况下,
	// 添加分隔符可以将多余的空位占用掉,以免部件调整自身大小以占用所有空位
	// 在lab的前后加上addStretch()可以使得lab居中哦~
	Bottom->addStretch();
	Bottom->addWidget(lab);
	Bottom->addStretch();

	/***************** 设置主布局管理器 ******************/
	QVBoxLayout * mainLayout = (QVBoxLayout *)getLayout(layout_V);
	mainLayout->addLayout(Top);
	mainLayout->addLayout(Mid);
	mainLayout->addLayout(Bottom);

	window->setLayout(mainLayout);
	window->show();

	return app.exec();
}

QLayout * getLayout(LAYOUT_TYPE type)
{
	QLayout * Layout;
	switch (type)
	{
	case layout_H:
		Layout = new QHBoxLayout;
		break;

	case layout_V:
		Layout = new QVBoxLayout;
		break;

	case layout_G:
		Layout = new QGridLayout;
		break;
	}
	return Layout;
}

好吧,就总结到这里~

时间: 2024-10-10 00:48:50

1.4 窗口部件的布局的相关文章

第二讲 窗口部件的布局与通信

本文概要:通过一个简单的例子,讲解如何通过布局(layout)来管理程序窗口中的窗口部件的几何形状, 以及如何通过信号和槽来同步窗口部件. #include <QApplication> #include <QSlider> #include <QSpinBox> #include <QHBoxLayout> int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget *w

自定义QT窗口部件外观之QStyle

自定义QT窗口部件外观 重新定义Qt内置窗口部件的外观常用的方法有两种:一是通过子类化QStyle 类或者预定义的一个样式,例如QWindowStyle,来定制应用程序的观感:二是使用Qt样式表. QStyle 类的使用 1.      准备必要的背景图片.在你想添加自定义风格的工程目录下新建一个文件夹“images”,将背景图片等放入文件夹“images”. 2.      点击Qt Creator的“文件”->“新建文件或工程”->模板选择“Qt”,再选择Qt资源文件->点击“选择”

C++ GUI Qt4编程-创建自定义窗口部件

C++ GUI Qt4编程-创建自定义窗口部件 Qtqt4 通过Qt窗口部件进行子类化或者直接对QWidget进行子类化,就可以创建自定义窗口部件,下面示范两种方式,并且也会说明如何把自定义窗口部件集成到Qt设计师中,这样就可以像使用内置的Qt窗口部件一样来使用它们,最后展示使用双缓冲技术(一种用于快速绘制的强大技术)的自定义窗口部件. 1.自定义Qt窗口部件 我们发现Qt窗口部件需要更多的自定义定制,这些定制可能要比它在Qt设计师里设置的属性或者对它调用的那些函数更多一些,一个简单而直接的解决

如何获得 Qt窗口部件在主窗口中的位置--确定鼠标是否在某一控件上与在控件上的位置

用Qt Creator 设计程序时,最方便的就是ui设计器,可以很容易的得到想要的布局. 但是这样自动布局带来的后果是很难知道窗口中某一部件在主窗口中的相对位置. 在处理子窗口鼠标事件时变的很麻烦.主窗口有菜单.工具条等,想用鼠标绘图, 把鼠标轨迹映射到窗口部件上,这些问题. 其实最主要的是获得窗口部件的起始点相对主窗口的位置. 例如:在主窗口拖入一个QScrollArea 在其上放一个QLabel用来显示鼠标事件. 可以在ui对象结构上看到如下结构. 大家知道,我们可以用pos()来获得某一窗

恢复VS2013窗口的默认布局

打开VS2013   在菜单栏中找到“Window”即“窗口”选项   单击窗口中的“reset Window layout"   点击恢复窗口布局后会有如下提示,选择Yes即可   此时即可以看到窗口的原始布局了   当然也可以通过设置自己定义窗口布局

Tkinter类之窗口部件类

Tkinter类之窗口部件类 Tkinter支持15个核心的窗口部件,这个15个核心窗口部件类列表如下: 窗口部件及说明: Button:一个简单的按钮,用来执行一个命令或别的操作. Canvas:组织图形.这个部件可以用来绘制图表和图,创建图形编辑器,实现定制窗口部件. Checkbutton:代表一个变量,它有两个不同的值.点击这个按钮将会在这两个值间切换. Entry:文本输入域. Frame:一个容器窗口部件.帧可以有边框和背景,当创建一个应用程序或dialog(对话)版面时,帧被用来组

CSS3+HTML5特效8 - 顶部和右侧固定,左侧随窗口变化的布局

原文:CSS3+HTML5特效8 - 顶部和右侧固定,左侧随窗口变化的布局 效果演示 实现原理 使用3个div(一个是顶部栏,一个是左侧栏,一个是右侧栏): 使用checkbox作为判断是否显示和隐藏右侧栏,点击显示和隐藏label实现最终效果. 代码说明 css + ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

【Qt学习笔记】窗口部件整理

关于Qt中窗口部件的学习 今天开始学习Qt的窗口部件,领略一下Qt的神奇之处,记得2012年的那年冬天,我还学Java呢,现在基本上和Java说再见了,不过对于嵌入式的开发Qt还是举足轻重的,我想趁着假期的时间,好好学习.考研之后发现一个问题,无论当初你学的有多明白,总会忘记,最好的方法就是将他们记录下来,甚至写下你当时的心情,如果有一天你需要了,回过头来看看,是一笔不错的财富. 1. QDialog类对话框 1.1 模态和非模态对话框 对于对话框,有模态(modal)和非模态(modeless

自定义窗口部件--Custom widget

通过继承的手段,子类原有的窗口部件 (1)改进法(promotion):新建一个项目,在UI界面拖QSpinBox部件到窗体中,右键点击部件.在弹出菜单中,选择“提升为”.(把下面两个文件加到项目中) #ifndef HEXSPINBOX_H #define HEXSPINBOX_H #include <QSpinBox> class QRegExpValidator; class HexSpinBox:public QSpinBox { Q_OBJECT public: HexSpinBox