九、容器组控件containers

九、容器组控件containers

9.1 组合框QGroupBox

分组框提供框架、顶部的标题、键盘快捷键,并在自身内部显示各种其他小部件。键盘快捷方式将键盘焦点移动到组框的子小组件之一。

QGroupBox 还允许您设置标题(通常在构造函数中设置)和标题 对齐方式 。可以选中 组框。启用或禁用可选中组框中的子小组件,具体取决于是否选中 了组框。

您可以通过启用 flat 属性来最大程度地减少分组框的空间消耗。在大多数样式 中,启用此属性会导致删除框架的左、右和下边缘。

QGroupBox 不会自动布置子小部件(通常是 QCheckBox es 或 QRadioButton s,但可以是任何小部件)。

这次我们创建QWidget工程,并且只在widget.cpp中完成代码。

widget.cpp

我们创建一个单选按钮组合框。

    QGridLayout *gl=new QGridLayout(this);

    QGroupBox *gb1=new QGroupBox("单选按钮组合框");
    QRadioButton *rb1=new QRadioButton("单选按钮1");
    QRadioButton *rb2=new QRadioButton("单选按钮2");

    QVBoxLayout *vbl=new QVBoxLayout;
    vbl->addWidget(rb1);
    vbl->addWidget(rb2);
    gb1->setLayout(vbl);
    gl->addWidget(gb1,0,0,1,1);

首先我们创建一个布局对象用来对组合框布局,然后创建一个组合框对象、两个单选按钮对象和一个垂直布局对象,垂直布局对象用来对单选按钮进行布局的。

这时候我们应该先把单选按钮对象放入到垂直布局里,然后再把垂直布局对象放入到组合框,最后再对组合框进行布局。

以下依次类推

    QGroupBox *gb2=new QGroupBox("复选框按钮组合框");
    QCheckBox *cb1=new QCheckBox("复选框1");
    QCheckBox *cb2=new QCheckBox("复选框2");
    cb1->setChecked(true);

    QVBoxLayout *vbl2=new QVBoxLayout;
    vbl2->addWidget(cb1);
    vbl2->addWidget(cb2);
    gb2->setLayout(vbl2);
    gl->addWidget(gb2,0,1,1,1);


    QGroupBox *gb3=new QGroupBox("综合按钮组合框");
    gb3->setCheckable(true);
    gb3->setChecked(true);

    QPushButton *pb1=new QPushButton("命令按钮1");
    QPushButton *pb2=new QPushButton("命令按钮2");
    pb2->setCheckable(true);
    pb2->setChecked(true);
    QPushButton *pb3=new QPushButton("命令按钮3");

    //给命令按钮添加子菜单
    QMenu *m=new QMenu(this);
    m->addAction("zhangsan");
    m->addAction("lisi");
    m->addAction("wangwu");
    pb3->setMenu(m);

    QVBoxLayout *vbl3=new QVBoxLayout;
    vbl3->addWidget(pb1);
    vbl3->addWidget(pb2);
    vbl3->addWidget(pb3);
    gb3->setLayout(vbl3);
    gl->addWidget(gb3,0,2,1,1);

 setCheckable(bool):

此属性用于确定组框的标题中是否有复选框
如果此属性为true,则组框将使用复选框代替普通标签显示其标题。如果选中复选框,则启用组框的子框;否则,它们将被禁用并无法访问。
默认情况下,组框不可选中。
如果为组框启用了此属性,则还将在初始时选中该属性,以确保启用了其内容。

QAction *QMenu::addAction(const QString &text):

这个方便的函数创建一个带有文本的新操作。该函数将新创建的操作添加到菜单的操作列表中,并返回该操作。
QMenu获取返回的QAction的所有权。

完整代码

#include "widget.h"
#include "ui_widget.h"

#include<QGroupBox>
#include<QPushButton>
#include<QRadioButton>
#include<QCheckBox>
#include<QGridLayout>
#include<QVBoxLayout> //可以在水平方向和垂直方向进行排列的控件,QHBoxLayout/QVBoxLayout所继承
#include<QMenu>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QGridLayout *gl=new QGridLayout(this);

    QGroupBox *gb1=new QGroupBox("单选按钮组合框");
    QRadioButton *rb1=new QRadioButton("单选按钮1");
    QRadioButton *rb2=new QRadioButton("单选按钮2");

    QVBoxLayout *vbl=new QVBoxLayout;
    vbl->addWidget(rb1);
    vbl->addWidget(rb2);
    gb1->setLayout(vbl);
    gl->addWidget(gb1,0,0,1,1);



    QGroupBox *gb2=new QGroupBox("复选框按钮组合框");
    QCheckBox *cb1=new QCheckBox("复选框1");
    QCheckBox *cb2=new QCheckBox("复选框2");
    cb1->setChecked(true);

    QVBoxLayout *vbl2=new QVBoxLayout;
    vbl2->addWidget(cb1);
    vbl2->addWidget(cb2);
    gb2->setLayout(vbl2);
    gl->addWidget(gb2,0,1,1,1);


    QGroupBox *gb3=new QGroupBox("综合按钮组合框");
    gb3->setCheckable(true);
    gb3->setChecked(true);

    QPushButton *pb1=new QPushButton("命令按钮1");
    QPushButton *pb2=new QPushButton("命令按钮2");
    pb2->setCheckable(true);
    pb2->setChecked(true);
    QPushButton *pb3=new QPushButton("命令按钮3");

    //给命令按钮添加子菜单
    QMenu *m=new QMenu(this);
    m->addAction("zhangsan");
    m->addAction("lisi");
    m->addAction("wangwu");
    pb3->setMenu(m);

    QVBoxLayout *vbl3=new QVBoxLayout;
    vbl3->addWidget(pb1);
    vbl3->addWidget(pb2);
    vbl3->addWidget(pb3);
    gb3->setLayout(vbl3);
    gl->addWidget(gb3,0,2,1,1);

}

Widget::~Widget()
{
    delete ui;
}

9.2 滚动区域QScrollArea

卷动区域用于在框架内显示子级 Widget 的内容。若 Widget 超过框架大小,视图可以提供滚动条,以便可以查看子级小部件的整个区域。指定子级 Widget 必须采用 setWidget ()。

main.cpp

#include "widget.h"

#include <QApplication>
#include<QScrollArea>
#include<QLabel>
#include<QGridLayout>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;

    w.resize(300,200);

    QLabel *lb=new QLabel;
    lb->setScaledContents(true);
    QImage imge("E:/blog/source/img/wallhaven-3k2y79.jpg");
    lb->setPixmap(QPixmap::fromImage(imge));

    QScrollArea *sa=new QScrollArea;

    //居中
    sa->setAlignment(Qt::AlignCenter);

    sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    sa->setWidget(lb);

    QGridLayout *gl=new QGridLayout;
    gl->addWidget(sa);

    w.setLayout(gl);


    w.show();
    return a.exec();
}

下方按钮可以让图片进行滑动。 

void setScaledContents(bool):

此属性用于确定标签是否缩放其内容以填充所有可用空间。
当启用并且标签显示像素图时,它将缩放像素图以填充可用空间。
此属性的默认值为false。

void setPixmap(const QPixmap &):

这个属性保存标签的像素图
如果没有设置像素图,将返回nullptr。
设置像素图清除之前的任何内容。好友快捷方式(如果有)被禁用。

QPixmap QPixmap::fromImage(const QImage &image(图片), Qt::ImageConversionFlags flags = Qt::AutoColor):

使用指定的标志来控制转换,将给定的图像转换为像素图。flags参数是Qt::ImageConversionFlags的位或。为标志传递0将设置所有默认选项。
在单色和8位图像的情况下,图像首先转换为32位像素图,然后用颜色表中的颜色填充。如果这个操作太昂贵,你可以使用QBitmap::fromImage()代替。

enum Qt::ScrollBarPolicy

9.3 标签小部件QTabWidget

选项卡小部件提供选项卡栏 (见 QTabBar ) 和页面区域用于显示每选项卡相关页面。默认情况下,选项卡栏展示在页面区域上方,但有不同可用配置 (见 TabPosition )。每选项卡关联不同 Widget (称为页面)。页面区域仅展示当前页面。所有其它页面被隐藏。用户可以展示不同页面通过点击其选项卡或按下其 Alt+ letter 快捷键若有的话。

通常,使用 QTabWidget 的方式是履行以下:

  1. 创建 QTabWidget。
  2. 创建 QWidget 对于每选项卡对话框页面,但不要为它们指定父级小部件。
  3. 将子级 Widget 插入页面小部件,使用布局正常安放它们。
  4. 调用 addTab () 或 insertTab () 将页面 Widget 放入选项卡小部件,为每选项卡赋予适合标签采用可选键盘快捷键。

选项卡位置的定义通过 tabPosition ,它们的形状通过 tabShape .

信号 currentChanged () 被发射当用户选择页面时。

当前页面索引可用作 currentIndex (),当前页面 Widget 采用 currentWidget ()。可以检索具有给定索引的页面小部件指针使用 widget (),和可以查找小部件的位置索引采用 indexOf ()。使用 setCurrentWidget () 或 setCurrentIndex () 以展示特定页面。

可以更改选项卡的文本和图标使用 setTabText () 或 setTabIcon ()。可以移除选项卡及其关联页面采用 removeTab ().

可以随时启用或禁用每选项卡 (见 setTabEnabled ())。若选项卡被启用,将正常绘制选项卡文本且用户可以选择该选项卡。若被禁用,将以不同方式绘制选项卡且用户无法选择该选项卡。注意,即使选项卡被禁用,页面仍可见 (例如:若所有选项卡被禁用)。

选项卡小部件可以是拆分复杂对话框的很好方式。另一方式是使用 QStackedWidget 提供在页面之间导航的一些手段,例如 QToolBar 或 QListWidget .

大多数 QTabWidget 功能的提供通过 QTabBar (在顶部,提供选项卡) 和 QStackedWidget (大部分区域,组织各个页面)。

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

#include<QTabWidget>
#include<QPushButton>
#include<QLabel>
#include<QGridLayout>
#include<QLineEdit>
#include<QMessageBox>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
    
    QTabWidget *tw;
    
private slots:
    void msgcommit();
};
#endif // WIDGET_H

widget.cpp

首先创建QTabWidget对象。

    tw=new QTabWidget(this);
    tw->setGeometry(20,20,560,360);
    tw->show();

 void QWidget::show():

显示小部件及其子小部件。
这相当于调用showFullScreen()、showMaximized()或setVisible(true),具体取决于平台对窗口标志的默认行为。

进行标签小部件测试。

    bool twui1=true;
    bool twui2=true;

    if(twui1)
    {
        QWidget *wg1=new QWidget();
        tw->addTab(wg1,"进程");

        QGridLayout *gl=new QGridLayout();
        QLabel *lb=new QLabel("请选择文件或文件夹");
        QLineEdit *le=new QLineEdit();
        QPushButton *pb=new QPushButton("消息框");

        connect(pb,SIGNAL(clicked(bool)),this,SLOT(msgcommit()));

        gl->addWidget(lb,0,0);
        gl->addWidget(le,0,1);
        gl->addWidget(pb,0,2);

        wg1->setLayout(gl);

    }
    if(twui2)
    {
        QWidget *wg2=new QWidget();
        tw->addTab(wg2,"性能");
    }

    void Widget::msgcommit()
    {
        QMessageBox::information(NULL,"test","QMessageBox测试成功",QMessageBox::Ok);
    }

 以上代码逻辑很简单,就是先安排好内层部件,最后再安排外层部件。

clicked(bool):

表示按钮被点击时发出的信号,带有一个bool类型的参数,表示按钮是否被按下。如果按钮被按下,则参数为true;如果按钮被释放,则参数为false。

int QMessageBox::information(QWidget *parent, const QString &title, const QString &text, int button0, int button1 = 0, int button2 = 0):

这个功能已经过时了。提供它是为了保持旧源代码的工作。我们强烈建议不要在新代码中使用它。
打开具有给定标题和文本的信息消息框。对话框最多可以有三个按钮。每个按钮,button0, button1和button2可以设置为以下值之一:
QMessageBox::NoButton
QMessageBox::Ok
QMessageBox::Cancel
QMessageBox::Yes
QMessageBox::No
QMessageBox::Abort
QMessageBox::Retry
QMessageBox::Ignore
QMessageBox::YesAll
QMessageBox::NoAll
如果您不需要所有三个按钮,请将最后一个按钮或最后两个按钮设置QMessageBox::NoButton。
一个按钮可以用QMessageBox::Default进行OR-ed,另一个按钮可以用QMessageBox::Escape进行OR-ed。返回被点击按钮的标识(QMessageBox::Ok,或QMessageBox::No,等等)。
消息框是一个应用程序模态对话框。
警告:不要在对话框执行期间删除父级。如果您想这样做,您应该使用QMessageBox构造函数之一自己创建对话框。

完整代码

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    this->setGeometry(300,200,600,400);

    tw=new QTabWidget(this);
    tw->setGeometry(20,20,560,360);
    tw->show();

    bool twui1=true;
    bool twui2=true;

    if(twui1)
    {
        QWidget *wg1=new QWidget();
        tw->addTab(wg1,"进程");

        QGridLayout *gl=new QGridLayout();
        QLabel *lb=new QLabel("请选择文件或文件夹");
        QLineEdit *le=new QLineEdit();
        QPushButton *pb=new QPushButton("消息框");

        connect(pb,SIGNAL(clicked(bool)),this,SLOT(msgcommit()));

        gl->addWidget(lb,0,0);
        gl->addWidget(le,0,1);
        gl->addWidget(pb,0,2);

        wg1->setLayout(gl);

    }
    if(twui2)
    {
        QWidget *wg2=new QWidget();
        tw->addTab(wg2,"性能");
    }
}

Widget::~Widget()
{
    delete ui;
}

void Widget::msgcommit()
{
    QMessageBox::information(NULL,"test","QMessageBox测试成功",QMessageBox::Ok);
}

9.4 停靠窗口部件QDockWidget

QDockWidget 提供了停靠小部件的概念,也称为工具选项板或实用程序窗口。Dock 窗口是放置在 QMainWindow 中央 widget 周围的 dock widget 区域中的辅助窗口。

停靠窗口可以在其当前区域内移动,移动到新区域并由最终用户浮动(例如,取消停靠)。QDockWidget API 允许程序员限制 Dock Widget 移动、浮动和关闭的能力,以及它们可以放置的区域。

这次我们创建QMainWindow工程。而且只在mainwindow.cpp文件里写代码。

我们创建一个QDockWidget对象,并且设置颜色。

    QDockWidget *dw=new QDockWidget("停靠窗口部件测试",this);

    //设置颜色
    QPalette p;
    p.setColor(QPalette::Background,Qt::cyan);
    dw->setAutoFillBackground(true);
    dw->setPalette(p);


void setAutoFillBackground(bool enabled(启动)):

此属性保留小部件背景是否自动填充
如果启用,此属性将导致Qt在调用paint事件之前填充小部件的背景。使用的颜色由小部件调色板中的QPalette::Window颜色角色定义。
此外,Windows总是被QPalette::Window填充,除非设置了WA_OpaquePaintEvent或WA_NoSystemBackground属性。
如果小部件的父类具有静态渐变背景,则此属性不能关闭(即设置为false)。

警告:与Qt样式表一起谨慎使用此属性。当小部件具有具有有效背景或边框图像的样式表时,此属性将自动禁用。
默认情况下,此属性为false。

 接下来实现一些学历层次信息。

    // 学历层次
    QLabel *lab=new QLabel("学历层次:");

    QComboBox *cbx=new QComboBox();
    cbx->addItem("小学");
    cbx->addItem("初中");
    cbx->addItem("高中");
    cbx->addItem("专科");
    cbx->addItem("本科");
    cbx->addItem("硕士研究生");
    cbx->addItem("博士研究生");

    QPushButton *pbt1=new QPushButton("清华大学");
    QPushButton *pbt2=new QPushButton("北京大学");

    // 通过栅格布局(网格布局)
    QGridLayout *glayout=new QGridLayout();
    glayout->addWidget(lab,0,0,1,1);
    glayout->addWidget(cbx,0,1,1,1);
    glayout->addWidget(pbt1,1,0,1,1);
    glayout->addWidget(pbt2,1,1,1,1);

    glayout->setHorizontalSpacing(10);
    glayout->setVerticalSpacing(10);
    glayout->setContentsMargins(20,20,20,20);


    QWidget *wgt=new QWidget();
    wgt->setLayout(glayout);
    dw->setWidget(wgt);



    dw->setMaximumSize(300,300);

我们可以拖动窗口进行位置停靠。

void QWidget::setMaximumSize(int maxw, int maxh):

这个函数对应于setMaximumSize(QSize(maxw, maxh))。将最大宽度设置为maxw,最大高度设置为maxh。

完整代码

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include<QDockWidget>
#include<QLabel>
#include<QComboBox>
#include<QPushButton>
#include<QGridLayout>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    this->setGeometry(200,200,500,400);

    QDockWidget *dw=new QDockWidget("停靠窗口部件测试",this);

    //设置颜色
    QPalette p;
    p.setColor(QPalette::Background,Qt::cyan);
    dw->setAutoFillBackground(true);
    dw->setPalette(p);

    // 学历层次
    QLabel *lab=new QLabel("学历层次:");

    QComboBox *cbx=new QComboBox();
    cbx->addItem("小学");
    cbx->addItem("初中");
    cbx->addItem("高中");
    cbx->addItem("专科");
    cbx->addItem("本科");
    cbx->addItem("硕士研究生");
    cbx->addItem("博士研究生");

    QPushButton *pbt1=new QPushButton("清华大学");
    QPushButton *pbt2=new QPushButton("北京大学");

    // 通过栅格布局(网格布局)
    QGridLayout *glayout=new QGridLayout();
    glayout->addWidget(lab,0,0,1,1);
    glayout->addWidget(cbx,0,1,1,1);
    glayout->addWidget(pbt1,1,0,1,1);
    glayout->addWidget(pbt2,1,1,1,1);

    glayout->setHorizontalSpacing(10);
    glayout->setVerticalSpacing(10);
    glayout->setContentsMargins(20,20,20,20);


    QWidget *wgt=new QWidget();
    wgt->setLayout(glayout);
    dw->setWidget(wgt);



    dw->setMaximumSize(300,300);

}

MainWindow::~MainWindow()
{
    delete ui;
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mo Yan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值