3.3布局管理
在设计复杂的GUI用户界面时,仅通过指定父子对象之间的位置关系以期达到加载和排列窗口部件的方法是行不通的。我们可以使用布局管理相关的类帮我们自动管理对象之间的关系。
QT提供了QHBoxLayout类、QVBoxLayout类及QgridLayout类等的基本布局管理,分别是水平排列布局、垂直排列布局和网格排列布局。它们之间的继承关系如下:
以QVBoxLayout使用为例:
1、包含头文件:#include <QVBoxLayout>
2、构造对象:QVBoxLayout layout;
3、在布局管理对象layout中加载窗口部件:
layout.addWidget(&button);
layout.addWidget(&lineEdit);
4、在窗口中设置布局:w.setLayout(&layout);
现在层次关系变为当前窗体中有一个垂直布局layout,这个layout中有一个按钮和一个文本输入框。
vlayout.addWidget(&button1); vlayout.addWidget(&button2); vlayout.addStretch(1); vlayout.addWidget(&button3); vlayout.addWidget(&lineEdit);
//增加一个弹簧,防止往下进行伸缩 vlayout.addStretch(1); |
布局嵌套:
QVBoxLayoutlayout; layout.addStretch(1); layout.addWidget(&button); layout.addWidget(&button1); layout.addWidget(&button2); layout.addWidget(&lineEdit); layout.addStretch(1);
QHBoxLayoutlayout1; layout1.addStretch(1); layout1.addLayout(&layout); layout1.addStretch(1);
w.setLayout(&layout1); |
布局分析:
窗口中有一个水平布局layout1,水平布局中有一个垂直布局layout,垂直布局中有3个button和一个文本输入框。水平布局的两边和垂直布局的上下都设置了stretch,可以将它们想象为弹簧,将控件王中间挤压。
网格布局的伸缩设置:
QGridLayoutlayout2; layout2.addWidget(&button,1,1); layout2.addWidget(&button1,1,2); layout2.addWidget(&button2,2,1); layout2.addWidget(&lineEdit,2,2); layout2.setColumnStretch(0,1); layout2.setColumnStretch(3,1); layout2.setRowStretch(0,1); layout2.setRowStretch(3,1); |
布局分析
| |||
| button | button1 |
|
button2 | lineEdit1 | ||
|
做一个登陆框
QGridLayoutlayout2; QLineEdit*password=newQLineEdit(); password->setEchoMode(QLineEdit::Password);
layout2.addWidget(newQLabel("username"),1,1); layout2.addWidget(newQLineEdit,1,2); layout2.addWidget(newQLabel("password"),2,1); layout2.addWidget(password,2,2);
QHBoxLayout*box=newQHBoxLayout(); box->addStretch(1); box->addWidget(newQPushButton("登陆")); layout2.addLayout(box,3,2); layout2.setColumnStretch(0,1); layout2.setColumnStretch(3,1); layout2.setRowStretch(0,1); layout2.setRowStretch(4,1); w.setLayout(&layout2); |
3.4常用控件介绍
3.4.1常用控件需要的头文件加载
#include<QWidget> #include<QLabel> //标签页 #include<QLineEdit> //单行文本输入框 #include<QVBoxLayout> #include<QTextEdit> //多行文本输入框 #include<QPushButton> //按钮 #include<QRadioButton> //单选按钮 #include<QCheckBox> //选择框 #include<QGroupBox> //组合框 #include<QComboBox> //下拉框 #include<QSlider> //滑动器 #include<QSpinBox> //选值框 #include<QDateEdit> //日期输入框 #include<QTimeEdit> //时间输入框 #include<QDateTimeEdit> //日期时间输入框 #include<QLCDNumber> //数码显示器 |
控件变量定义: |
QVBoxLayout*_vBox; QLabel*_label; QLineEdit*_lineEdit; QTextEdit*_textEdit; QPushButton*_button; QRadioButton*_radio; QCheckBox*_checkbox; QGroupBox*_groupBox; QComboBox*_combo; QSlider*_slider; QSpinBox*_spinBox; QDateEdit*_dateEdit; QTimeEdit*_timeEdit; QDateTimeEdit*_DTEdit; QLCDNumber*_lcd; |
控件初始化: |
_vBox=newQVBoxLayout(this); _label=newQLabel("label",this); _lineEdit=newQLineEdit(this); _textEdit=newQTextEdit(this); _button=newQPushButton("button",this); _radio=newQRadioButton("RadioButton",this); _checkbox=newQCheckBox("checkBox",this); _groupBox=newQGroupBox("group",this); _combo=newQComboBox(this); _slider=newQSlider(this); _spinBox=newQSpinBox(this); _dateEdit=newQDateEdit(this); _timeEdit=newQTimeEdit(this); _DTEdit=newQDateTimeEdit(this); _lcd=newQLCDNumber(this); |
在垂直布局种加载控件: |
_vBox->addWidget(_label); _vBox->addWidget(_lineEdit);; _vBox->addWidget(_textEdit); _vBox->addWidget(_button); _vBox->addWidget(_radio); _vBox->addWidget(_checkbox); _vBox->addWidget(_groupBox); _vBox->addWidget(_combo); _vBox->addWidget(_slider); _vBox->addWidget(_spinBox); _vBox->addWidget(_dateEdit); _vBox->addWidget(_timeEdit); _vBox->addWidget(_DTEdit); _vBox->addWidget(_lcd); |
3.4.2常用控件使用
label: 标签、显示静态文本和图片 |
支持html格式: // 设置文本 QLabel*label=newQLabel("<h1>lable</h1>"); // 设置颜色 QLabel*label=newQLabel("<fontcolor=red>lable</font>"); // 设置链接 label= newQLabel("<a href=www.baidu.com>baidu</a>"); // 设置图片 label= newQLabel("<imgsrc=../photo/1.gif></img>"); label->setPixmap(QPixmap("../aaa.png")); |
打开链接:为了不写很多槽函数,可以使用C++的lambda表达式,方法在工程管理文件中增加 CONFIG+=C++11 使用的时候相当于将槽函数写成一个匿名函数。 |
QLabel*label=newQLabel("<ahref=www.baidu.com>baidu</a>"); vlayout->addWidget(label); connect(label,&QLabel::linkActivated,[](QStringstr){ qDebug()<<str; QDesktopServices::openUrl(str); }); |
textEdit |
connect(_textEdit,SIGNAL(textChanged()),this,SLOT(textEditChage())); |
voidMyWidget::textEditChage() { QStringstr=_textEdit->toPlainText(); if(str.contains("/ku")) { str.replace("/ku","<imgsrc=../photo/1.gif></img>"); _textEdit->setText(str); } } |
RadioButton、CheckBox、GroupBox |
未分组的时候加载很多radioButton选择的时候只能选一个,可以通过QGroupBox进行分组 |
QVBoxLayout*vBox1=newQVBoxLayout(this); vBox1->addWidget(newQRadioButton("A")); vBox1->addWidget(newQRadioButton("B")); vBox1->addWidget(newQRadioButton("C")); vBox1->addWidget(newQRadioButton("D"));
QVBoxLayout*vBox2=newQVBoxLayout(this); vBox2->addWidget(newQRadioButton("A")); vBox2->addWidget(newQRadioButton("B")); vBox2->addWidget(newQRadioButton("C")); vBox2->addWidget(newQRadioButton("D"));
QVBoxLayout*vBox3=newQVBoxLayout(this); vBox3->addWidget(newQRadioButton("A")); vBox3->addWidget(newQRadioButton("B")); vBox3->addWidget(newQRadioButton("C")); vBox3->addWidget(newQRadioButton("D"));
QGroupBox*groupBox=newQGroupBox("第一题",this); groupBox->setLayout(vBox1); QGroupBox*groupBox1=newQGroupBox("第二题",this); groupBox1->setLayout(vBox2); QGroupBox*groupBox2=newQGroupBox("第三题",this); groupBox2->setLayout(vBox3);
_vBox->addWidget(groupBox); _vBox->addWidget(groupBox1); _vBox->addWidget(groupBox2); |
ComboBox |
设置它的自动补全的时候自动补全对象初始化要用ComboBox 的model() |
_combo=newQComboBox(this); _combo->addItem("第一题"); _combo->addItem("第二题"); _combo->addItem("第三题"); _combo->setEditable(true); //_combo->setCompleter(newQCompleter(QStringList()<<"123"<<"abc")); _combo->setCompleter(newQCompleter(_combo->model())); connect(_combo,SIGNAL(currentIndexChanged(QString)),this,SLOT(comboChanged(QString))); |
voidMyWidget::comboChanged(QStringstr) { qDebug()<<str; if(str=="第一题") { _textEdit->setText("第一题内容"); } elseif(str=="第二题") { _textEdit->setText("第二题内容"); } elseif(str=="第三题") { _textEdit->setText("第三题内容"); } } |
QSlider、QSpinBox |
_slider->setMaximum(100); _slider->setMinimum(0); _spinBox->setMaximum(100); _spinBox->setMinimum(0); |
connect(_spinBox,SIGNAL(valueChanged(int)),_slider,SLOT(setValue(int))); connect(_slider,SIGNAL(valueChanged(int)),_spinBox,SLOT(setValue(int)));} |
4、消息基础
application能够知道哪个窗口在哪个位置,能知道应该由哪个窗口来接收消息,这个窗口会调用自己的消息处理函数。
窗口的 event()函数处理所有经过窗口的消息
消息处理函数是虚函数,使用要进行重载。