- 2.4 按钮组件
 - 2.5 布局组件
 
2.4 按钮组件
QPushButton、QRadioButton 、QCheckBox都从 QAbstractButton,拥有一些共同的属性,如下图所 示:

图标使用setIcon()来设置,文本可以在构造函数或通过 setText()来设置。 可以使用 isChecked() 检查是否被选 中。
-  
QPushButton
QPushButton 是Qt常用的控件之一,提供普通的按 钮功能。 通过信号槽机制接收触发信号并执行对应 动作。
 -  
QRadioButton
单选框默认开启自动互斥(autoExclusive)。如果 启用了自动互斥,属于同一个父部件的单选框的行为 就和属于一个互斥按钮组的一样。如果你需要为属于 同一父部件的单选框设置多个互斥按钮组,把它们加 入QButtonGroup中。
 -  
QCheckBox
它也是一个可选择的按钮 , 常见用途是在要求用户 选择一个或多个可用选项的情况下。 与单选按钮不 同,默认情况下复选框不是互斥的。 checkBox按钮 可以通过在QButtonGroup对象中添加它们而互斥。 每当选中或清除复选框时,它都会发出信号状态 Changed()。如果要在每次复选框更改状态时触发操 作,请连接到此信号。您可以使用 isChecked() 查询 复选框是否被选中。
注意:QCheckBox可以有两种状态,也可以有三种 状态(未选中,选中,半选),默认是两种状态。

 
创建基于QMainWindow的工程,如下图所示:

对应的代码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::on_pushButton_ok_clicked()
{
    // 构建个人信息字符串
    QString info = "我是";
    if (ui->radioButton_man->isChecked()) {
        info += "男生";
    } else if (ui->radioButton_woman->isChecked()) {
        info += "女生";
    } else {
        info = "性别保密";
    }
    info += ", 我平时喜欢:";
    // 处理喜好复选框
    if (ui->checkBox_backeball->checkState()) {
        info += ui->checkBox_backeball->text();
        info += ",";
    }
    if (ui->checkBox_cartoon->checkState()) {
        info += ui->checkBox_cartoon->text();
        info += ",";
    }
    if (ui->checkBox_game->checkState()) {
        info += ui->checkBox_game->text();
        info += ",";
    }
    if (ui->checkBox_reading->checkState()) {
        info += ui->checkBox_reading->text();
        info += ",";
    }
    if (ui->checkBox_swim->checkState()) {
        info += ui->checkBox_swim->text();
        info += ",";
    }
    // 替换最后一个逗号为句号
    int pos = info.lastIndexOf(",");
    info.replace(pos, 1, ".");
    // 设置文本浏览器显示个人信息
    ui->textBrowser->setText(info);
}
void MainWindow::on_pushButton_clear_clicked()
{
    // 清除单选框和复选框的选择状态,并清空文本浏览器
    ui->radioButton_man->setAutoExclusive(false);
    ui->radioButton_man->setChecked(false);
    ui->radioButton_man->setAutoExclusive(true);
    ui->radioButton_woman->setAutoExclusive(false);
    ui->radioButton_woman->setChecked(false);
    ui->radioButton_woman->setAutoExclusive(true);
    ui->checkBox_backeball->setChecked(false);
    ui->checkBox_cartoon->setChecked(false);
    ui->checkBox_game->setChecked(false);
    ui->checkBox_reading->setChecked(false);
    ui->checkBox_swim->setChecked(false);
    ui->textBrowser->clear();
}
 
2.5 布局组件
Qt 的界面设计使用了布局(Layout)功能。所谓布局, 就是界面上组件的排列方式,使用布局可以使组件有规 则地分布,并且随着窗体大小变化自动地调整大小和相 对位置。
Qt提供了QHBoxLayout类(水平排列布局), QVBoxLayout类(垂直排列布局),QGridLayout类(网格 排列布局)等基本布局管理。它们之间的继承关系如下图 所示。

在designer软件界面中我们可以看到:
 
每个组件的作用如下表所示。

addWidget()方法用于向布局中加入组件。
addLayout()方法用于向布局中加入子布局 。
LeftLayout = new QGridLayout(); //由于LeftLayout布局管理器不是主布局管理器,所以不用指定父窗口
QGridLayout *mainLayout = new QGridLayout(this); //mainLayout实现主布局,所有要指定父窗口
//QHBoxLayout默认采取的是以自左向右的方式顺序排列插入控件或子布局,也可以通过setDirection()方法设定排列的顺序
TopRightLayout->setDirection(QBoxLayout::RightToLeft);
//QHBoxLayout是水平布局,可以设定水平各个控件之间的间距
TopRightLayout = new QHBoxLayout();
TopRightLayout->setSpacing(20); //设定各个控件之间的间距为20
 
布局如下窗口:

代码方式:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QLabel>
#include <QLineEdit>
#include <QRadioButton>
#include <QPushButton>
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    // 初始化标签
    void initLabel();
    // 初始化输入框
    void initLineEdit();
    // 初始化布局
    void initLayout();
    // 初始化按钮
    void initBtn();
protected:
    // 标签
    QLabel *nameLabel;
    QLabel *ageLabel;
    QLabel *emailLabel;
    QLabel *numLabel;
    QLabel *sexLabel;
    // 输入框
    QLineEdit *ageLineEdit;
    QLineEdit *nameLineEdit;
    QLineEdit *emailLineEdit;
    QLineEdit *numLineEdit;
    // 单选按钮
    QRadioButton *mBtn;
    QRadioButton *wBtn;
    QPushButton *okBtn;
};
#endif // WIDGET_H
 
#include "widget.h"
#include <QFormLayout>
#include <QHBoxLayout>
#include <QVBoxLayout>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    // 构造函数里逐个调用
    this->initBtn();
    this->initLabel();
    this->initLineEdit();
    this->initLayout();
}
Widget::~Widget()
{
}
void Widget::initLabel()
{
    this->nameLabel = new QLabel("姓名:(&N)");
    this->ageLabel = new QLabel("年龄:(&A)");
    this->emailLabel = new QLabel("邮箱:(&E)");
    this->numLabel = new QLabel("电话号码:(&N)");
    this->sexLabel = new QLabel("性别");
}
void Widget::initLineEdit()
{
    this->nameLineEdit = new QLineEdit;
    this->ageLineEdit = new QLineEdit;
    this->emailLineEdit = new QLineEdit;
    this->numLineEdit = new QLineEdit;
}
// 初始化布局
void Widget::initLayout()
{
    nameLabel->setBuddy(nameLineEdit);
    ageLabel->setBuddy(ageLineEdit);
    emailLabel->setBuddy(emailLineEdit);
    // 创建一个表格类布局
    QFormLayout *headerLayout = new QFormLayout;
    headerLayout->addRow(nameLabel, nameLineEdit);
    headerLayout->addRow(ageLabel, ageLineEdit);
    headerLayout->addRow(emailLabel, emailLineEdit);
    headerLayout->addRow(numLabel, numLineEdit);
    // 创建水平布局类,意思是横线方向的布局
    QHBoxLayout *sexLayout = new QHBoxLayout;
    sexLayout->addWidget(sexLabel);
    sexLayout->addWidget(mBtn);
    sexLayout->addWidget(wBtn);
    // 空隙
    QSpacerItem *vSpacer = new QSpacerItem(30, 30);
    QSpacerItem *hSpacer = new QSpacerItem(150, 20);
    // 创建水平布局
    QHBoxLayout *okLayout = new QHBoxLayout;
    // 把上面创建的空隙先添加进来
    okLayout->addItem(hSpacer);
    // 把按钮添加到布局
    okLayout->addWidget(okBtn);
    // 创建一个垂直布局,作为主布局,把之前创建的布局都添加到这个布局中
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->addLayout(headerLayout);
    mainLayout->addLayout(sexLayout);
    mainLayout->addItem(vSpacer);
    mainLayout->addLayout(okLayout);
    mainLayout->setMargin(50);
    mainLayout->setSpacing(10);
    // 把垂直布局设置为当前界面的
    this->setLayout(mainLayout);
}
void Widget::initBtn()
{
    this->mBtn = new QRadioButton("男");
    this->wBtn = new QRadioButton("女");
    this->okBtn = new QPushButton("确定");
}
 
可视化方式:
第一步:

第二步
 
第三步:

第四步:




















