百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Qt C++实战:Qt如何实现界面布局自动排版、自定义滚动条?

haoteby 2024-11-09 13:01 6 浏览

在一些实际项目中,程序配置界面会有很多的配置参数项(超过几百条),并且这些配置参数项需要通过接口来动态添加。本文就来重点讲下,Qt界面如何利用滚动条显示超多配置参数项,同时还要实现界面布局自动排版等功能。

本示例利用QGridLayhout网格布局管理器,来管理所有的配置参数项,实现界面布局自动排版;同时利用QScrollArea实现界面自定义滚动条的功能,当配置参数项的显示超出当前界面的可视高度,自动显示垂直滚动条。

  • 先看最终配置界面效果:

截图一:

截图二:

下面开始编码实现。

2 增加配置参数项目界面

增加一个继承于QWidget的ui界面类CheckBoxSetItemsWidget。这个类主要有二个作用,一是QWidget做为封装,可以方便的集成到别的界面;二是单独类设计可以添加到QScrollArea实现滚动条功能。

首先需要先修改CheckBoxSetItemsWidget界面为垂直布局(QVBoxLayout),修改方式详见文末。

然后在上方放一个水平布局管理器(QHBoxLayout),在下方放一个网格布局管理器(QGridLayout)。

在界面上方的水平布局管理器里面,添加一个QCheckBox用于实现全选和反选,和一个水平弹簧(QSpacerItem)用于在水平方向自动撑开。

CheckBoxSetItemsWidget.ui界面设计如下图:

  • CheckBoxSetItemsWidget类设计:

#ifndef CHECKBOXSETITEMSWIDGET_H
#define CHECKBOXSETITEMSWIDGET_H

#include <QWidget>
#include <QString>

namespace Ui {
class CheckBoxSetItemsWidget;
}

class CheckBoxSetItemsWidget : public QWidget
{
    Q_OBJECT

public:
    explicit CheckBoxSetItemsWidget(QWidget *parent = nullptr);
    ~CheckBoxSetItemsWidget();

    // 设置一行显示几个配置参数
    void setRowCount(int iRowCount = 5);

    // 添加配置参数项函数
    void addCheckBoxItem(const QString& qstrName, bool bChecked = true);

private slots:
    // 全选&反选功能函数
    void slotSelectAllClicked(bool checked = false);

private:
    Ui::CheckBoxSetItemsWidget *ui;
    // 一行配置5个QCheckBox配置参数项
    int m_iRowCount{ 5 };
};

#endif // CHECKBOXSETITEMSWIDGET_H
  • 构造函数代码:

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

    // 初始界面
    ui->m_pCheckBoxSelectAll->setText("全选");
    ui->m_pCheckBoxSelectAll->setChecked(true);

    // 连接信号槽
    connect(ui->m_pCheckBoxSelectAll, &QCheckBox::clicked, this, &CheckBoxSetItemsWidget::slotSelectAllClicked);
}
  • 添加配置参数项代码:
// 添加配置参数项函数代码。
void CheckBoxSetItemsWidget::addCheckBoxItem(const QString &qstrName, bool bChecked)
{
    QCheckBox* p_check_box = new QCheckBox(qstrName, this);
    p_check_box->setChecked(bChecked);
    int i_row = ui->m_pGridLayout->count() / m_iRowCount;
    int i_col = ui->m_pGridLayout->count() % m_iRowCount;
    ui->m_pGridLayout->addWidget(p_check_box, i_row, i_col);
}
全选&反选代码:
// 全选&反选功能函数代码
void CheckBoxSetItemsWidget::slotSelectAllClicked(bool checked)
{
    int i_count = ui->m_pGridLayout->count();
    for (int i = 0; i < i_count; ++i)
    {
        QCheckBox* p_check_box = (QCheckBox*)ui->m_pGridLayout->itemAt(i)->widget();
        assert(nullptr != p_check_box);
        p_check_box->setChecked(checked);
    }
}

3 集成配置参数项目界面

我们把CheckBoxSetItemsWidget配置参数项目界面集成到主界面。

首先需要先修改MainWindow界面为垂直布局(QVBoxLayout),修改方式详见文末。

  • MainWindow类设计:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H


#include <QMainWindow>


QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE


class MainWindow : public QMainWindow
{
    Q_OBJECT


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


    // 添加模拟配置参数项数据
    void addParamDatas();


protected:
    // 初始界面
    void initForm();


private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
  • 构造函数代码:
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::IMainWindow)
{
    ui->setupUi(this);
    this->setWindowTitle("QScrollArea & QGridLayout & QCheckBox实战示例");


    initForm();
    addParamDatas();
}
  • 初始界面代码:
void MainWindow::initForm()
{
    // 创建滚动条控件对象
    auto p_scroll_area = new QScrollArea(this);
    // 创建配置参数项界面
    auto* p_check_box_items_widget = new CheckBoxSetItemsWidget(p_scroll_area);
    // 将配置参数项界面加入到滚动条
    p_scroll_area->setWidget(p_check_box_items_widget);
    p_scroll_area->setWidgetResizable(true);
    // 将滚动条控件加入到界面布局
    QLayout* p_layout = ui->centralwidget->layout();
    p_layout->addWidget(p_scroll_area);
}
  • 添加配置参数项代码:
// 添加配置参数项数据
void MainWindow::addParamDatas()
{
    auto* p_scroll_area = (QScrollArea*)ui->centralwidget->layout()->itemAt(0)->widget();
    auto* p_check_box_items_widget = (CheckBoxSetItemsWidget*)p_scroll_area->widget();
    // 生成300组模拟配置参数
    for (int i = 0; i < 300; ++i)
    {
        QString qstr_name = QString("CheckBox%0").arg(i);
        p_check_box_items_widget->addCheckBoxItem(qstr_name, true);
    }
}

附录1:如何手工修改QWidget界面的默认布局

  • 修改CheckBoxSetItemsWidget界面为垂直布局(QVBoxLayout):

右键CheckBoxSetItemsWidget.ui文件,用(普通文本编辑器)打开,找到()代码,在下面增加()一行代码,保存关闭文本编辑器。

CheckBoxSetItemsWidget.ui源码如下例子:


<ui version="4.0">
 <author/>
 <comment/>
 <exportmacro/>
 <class>CheckBoxSetItemsWidget</class>
 <widget class="QWidget" name="CheckBoxSetItemsWidget">
  <layout class="QVBoxLayout" name="verticalLayout_1" />
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
 </widget>
 <pixmapfunction/>
 <connections/>
</ui>
  • 修改MainWindow界面为垂直布局(QVBoxLayout):

右键MainWindow.ui文件,用(普通文本编辑器)打开,找到()代码,在下面增加()一行代码,保存关闭文本编辑器。

MainWindow.ui源码如下例子:


<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>IMainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout_1"/>
  </widget>
  <widget class="QMenuBar" name="menubar"/>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

相关推荐

在线抓取网页源码(爬虫获取网页源代码)

经验分享:如何解决爬虫抓取时的网页源码不全问题爬虫是一种常用的数据采集工具,可以帮助我们快速获取互联网上的各种信息。然而,很多人在使用爬虫时都会遇到一个普遍的问题,那就是爬虫抓取的网页源码总是不完整。...

40个图源二维码分享及使用方法(图片二维码生成器在线制作二维码)

我们曾在《35个图源二维码分享及使用方法》一文中,为你分享了35个图源二维码。...

45个图源二维码分享及使用方法(图源是啥)

我们曾在《40个图源二维码分享及使用方法》一文中,为你分享了40个图源二维码。...

电子书管理软件Calibre 8.0.1发布:改善支持Kobo,优化新闻源等

IT之家3月22日消息,Calibre是一款免费、开源的电子书管理工具,支持整理、转换和阅读多种格式的电子书。最新发布的8.0.1版本带来了多项功能改进和问题修复,进一步提升了用户体验。...

软网推荐:一键生成不同网站RSS订阅源

为了关注自己喜欢的网站内容,以前最常见的方法是订阅RSS源,这样在内容更新的时候就会自动进行推送。但由于RSS现在已经不是主流的阅读方式,所以并不是所有的网站都提供RSS订阅,这时我们就得另辟蹊径了。...

消费曝光台|29.9元充100元话费?到手是15张满减优惠券

近日,山西大同的王先生向澎湃质量报告投诉平台反映,他在使用手机时收到一条弹窗广告,称他获得了“29.9元充值100元话费券”。王先生充值并下载了APP潮物圈后才发现,100元的话费实际上是15张5元和...

玩Kodi的IPTV插件必备技能——直播源地址抓包教程

准备工具:谷歌浏览器(Google)或者其他浏览器(不常用的或再安装一个浏览器)Potplayerm3u8直播源文件或者Gitee个人工作台...

i.MX6加载Ubuntu镜像的教程(ubuntu添加镜像源)

基于迅为IMX6开发板安装好虚拟机之后,用户就可以加载Ubuntu12.04.2镜像。用户可以在网盘中下载“编译好的镜像”,该镜像已经安装好了编译Android4.4.2所需要的大部分软件...

嵌入式软件开发人员有必要学习系统移植的知识吗?ppt见文末

《从零开始学ARM》的配套视频说明...

ARM体系结构(10)-GPIO LED闪烁汇编代码实现(基于tiny4412)

接上一篇,我将介绍如何使用GPIO引脚GPM4_1来控制Tiny4412开发板上的LED2闪烁。本文将从原理、汇编代码、Makefile实现、程序编译和烧写等多个方面进行介绍,以便读者能够全面了解如何...

物联网学习路线图(物联网必学课程)

物联网技术近几年在我国获得了很好的发展,从目前的发展趋势来看,未来物联网发展前景一片大好。由此学习的人员也是越来越多,但是在学习物联网时很多人都容易忽略这样一件事——从未准备一份详尽的物联网学习路线图...

网卡DM9000裸机驱动开发详解(pro1000网卡驱动)

一、网卡1.概念网卡是一块被设计用来允许计算机在计算机网络上进行通讯的计算机硬件。由于其拥有MAC地址,因此属于OSI模型的第2层。它使得用户可以通过电缆或无线相互连接。...

Win10高分屏更改DPI后字体模糊?试试这个小工具

如果你使用的是大尺寸显示屏,拥有1920x1080或更大分辨率,可能你会选择设置一个较高的DPI缩放级别,比如125%或更高。这样屏幕上的内容看起来会更大一些,更容易阅读。在WindowsVista...

微软Windows竟内嵌Linux?这样玩挺有趣

在Windows上运行Linux?这其实不是新鲜事,20年前,就有黑客这么干过。微软的开发者博客刚刚公布,下一个Windows10版本,不仅自带Linux内核,而且还会通过Win...

上厕所别带手机!9 个错误动作增加你感染病毒的风险

随着复工的正式开始,很多小伙伴开始担心如何在上班过程中更好地保护自己。口罩准备好了,免洗洗手液准备好了,是不是就万无一失了?还真不是!你摸完电梯按钮的手,或者扶过地铁栏杆的手,不经意间揉一下眼睛、摸一...