qt5-入门-使用拖动方式创建Dialog

news2024/9/21 12:25:30

参考:
C++ GUI Programming with Qt 4, Second Edition

本地环境:
win10专业版,64位,Qt5.12


目录

  • 实现效果
  • 基本流程
  • 逐步实操
    • 1)创建和初始化子部件
    • 2)把子部件放进布局中
    • 3)设置tab顺序
    • 4)连接信号和槽 5)实现自定义的槽
  • 使用QDialogButtonBox
    • 拖动绘制
    • 代码
  • 排错
    • 设置了windowIcon但不显示

实现效果

打码的是logo。
在这里插入图片描述

基本流程

创建dialog的流程:

  1. 创建和初始化子部件;
  2. 把子部件放进布局中;
  3. 设置tab顺序;
  4. 连接信号和槽;
  5. 实现自定义的槽。

逐步实操

现在一步一步操作:

**注意:**我一开始是用Qt Creator的设计页面做的,所以截图都是设计页面,但是Qt Creator没有预览,稍微有点不方便,因此第三步我换到Qt Designer了,操作是一样的。

1)创建和初始化子部件

先新建一个dialog。
在这里插入图片描述
然后打开设计页面,放置几个小组件,如下图所示。不要在意对齐,后面会使用自动对齐:
在这里插入图片描述
各个对象的名称和所属的类如下图所示:
在这里插入图片描述
需要修改的属性有:

  • 左侧是okButton,修改text为OK,设置enable为false,设置default为true。default表示按回车会触发。
  • 右侧是cancelButton,需改text为cancel

然后需要设置label的buddy是lineEdit。

点击菜单栏-编辑-Edit buddies,然后左键点击label,出现箭头后拖动,连接到lineEdit上,如下图所示。
在这里插入图片描述
这样buddy就设置成功了。点击编辑菜单栏返回,也可以点击上方的工具条:
在这里插入图片描述

2)把子部件放进布局中

按住ctrl,然后依次选择label和lineEdit,单击工具条上的水平布局,此时布局成功:
在这里插入图片描述
然后对spacer和两个按钮做水平布局。随后,反选,单击垂直布局:
在这里插入图片描述
现在变成:
在这里插入图片描述
可以看到,窗口大小似乎偏大,点击工具条上的调整大小按钮,变成了最优尺寸:
在这里插入图片描述

3)设置tab顺序

设置tab顺序就是部件接受焦点(focus)的顺序,点击的是工具条上带数字的灰色按钮:
在这里插入图片描述
因为想要预览效果,我用Qt Designer打开了文件。

点击窗体-预览,可以看到各种风格下的效果。
在这里插入图片描述
windowsvista风格:
在这里插入图片描述

windows风格
在这里插入图片描述

fushion风格
在这里插入图片描述
那么如何套用这个格式呢?

在main.cpp中这样写:

#include <QApplication>
#include "ui_toolbasic.h"

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

    Ui::toolBasic ui;
    QDialog *dialog = new QDialog;
    ui.setupUi(dialog);
    dialog->show();

    return a.exec();
}

显示效果:logo显示正确。
在这里插入图片描述
代码说明:
ui_toolbasic.h是前面拖动后自动产生的文件,打开可以看到很多关于布局、绘制的代码:
在这里插入图片描述

4)连接信号和槽 5)实现自定义的槽

要实现的效果:限制lineEdit的输入格式,要求以字母开始,后跟一个数字,再跟0-2个数字。只有满足要求时,OK按钮才生效。
在这里插入图片描述

main.cpp


#include <QApplication>
//#include "ui_toolbasic.h"
#include "toolbasic.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    
    toolBasic* tb = new toolBasic;
    tb->show();

    return a.exec();
}

toolbasic.h

#ifndef TOOLBASIC_H
#define TOOLBASIC_H

#include <QDialog>
// 增加ui这一行,第一步生成form时是没有的
#include "ui_toolbasic.h"

namespace Ui {
class toolBasic;
}

// 声明
class QWidget;

class toolBasic : public QDialog, public Ui::toolBasic
{
    Q_OBJECT

public:
    //explicit toolBasic(QWidget *parent = nullptr);
    // 注释掉自动生成的构造函数,重写一个
    toolBasic(QWidget *parent = 0);
    ~toolBasic();

private:
    Ui::toolBasic *ui;
// 新增槽函数
private slots:
    void on_lineEdit_textChanged();

};

#endif // TOOLBASIC_H

toolBasic.cpp
需要注意的是, setupUi()会自动连接一些槽函数,只要槽函数满足格式:on_objectName_signalName(),也就是会蒋objectNamesignalName()连接起来,不用另外写。

因此,上面新增了槽函数on_lineEdit_textChanged()等于执行到setupUi()时,自动实现了这个连接:
connect(lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(on_lineEdit_textChanged()));

所以只需要实现这个槽函数,就能实现lineEdit内容改变后的自动处理过程。

#include "toolbasic.h"
#include <QRegularExpressionValidator>
#include <QWidget>


toolBasic::toolBasic(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::toolBasic)
{
    // setupUi()会自动连接一些槽函数,只要槽函数满足格式:on_objectName_signalName()
    setupUi(this);
    // 要求:以字母开头,后跟一个数字(1-9),然后跟0-2个数字(0-9)
    QRegularExpression regExp("[A-Za-z][1-9][0-9]{0,2}");
    lineEdit->setValidator(new QRegularExpressionValidator(regExp, this));
	// 把okButton连到QDialog::accept()槽函数. 
	// accept()关闭对话框,但是设置dialog的结果是QDialog::Accepted,也就是1
    connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
    // 把cancelButton连到QDialog::reject()
    // reject()也关闭对话框,但是设置结果为QDialog::Rejected,也就是0
    connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));

}

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

void toolBasic::on_lineEdit_textChanged() {
    // lineEdit有合法输入时,开启ok按钮
    okButton->setEnabled(lineEdit->hasAcceptableInput());
}

使用QDialogButtonBox

效果:
在这里插入图片描述
在创建界面时选择:Dialog with Buttons Bottom,起名myDialog。 (不要用这个,会报错)diyDialog。

拖动绘制

与前面相似,就是两个button变成了一个buttonBox。如果需要特殊一点的对齐,需要把预先出现在面板上的buttonBox删掉,不然spacer是放不好的。如果不删的话,上面两个connect也是自动实现了的,不用写。

另外,调整最佳尺寸的按钮会失效,需要手动调整尺寸。(自动的会很小,因为只有两个小组件)
在这里插入图片描述

代码

diydialog.h和main.cpp跟前面类似,不再重复。diydialog.cpp需要做一点修改:

#include <QRegularExpressionValidator>
#include <QWidget>
#include <QPushButton>
#include <QDialogButtonBox>
#include "diydialog.h"

diyDialog::diyDialog(QWidget *parent) :
    QDialog(parent)
{
    setupUi(this);
    QRegularExpression regExp("[A-Za-z][1-9][0-9]{0,2}");
    lineEdit->setValidator(new QRegularExpressionValidator(regExp, this));
	// 这里需要修改
    connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
    connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
}

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

void diyDialog::on_lineEdit_textChanged(){
	// 修改
    buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
                lineEdit->hasAcceptableInput());
}

注意,如果buttonBox->button这里提示invalid use of incomplete type 'class QPushButton',可能是没有引入<QPushButton>的原因,include上就解决了。
在这里插入图片描述

排错

设置了windowIcon但不显示

可能有问题的地方:

  1. 前缀写错

  2. 使用了错误的文件格式
    icon不支持ico格式,换成jpg或者png即可。

  3. 使用拖动方式,在designer中设置icon时,要选选择资源,不要选选择文件!!
    在这里插入图片描述

  4. 图片文件的路径写错
    在这篇文章里qt5-入门-信号槽理解+QMainWindow,我的路径是这样写的:openAction->setIcon(QIcon(":/pic.jpg"));,但是我现在把文件放到专门的文件夹下了,文件结构如下图:
    在这里插入图片描述
    如果直接写:/resources/img/xxx_logo.png,其实是访问不到的。更简单的方法是editor中查看res.qrc,右键复制path,可以看到复制结果是:://resources/img/xxx_logo.png,然后直接在代码里写:

    this->setWindowIcon(QIcon("://resources/img/xxx_logo.png"));
    

    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1481376.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

十八:Java8新特性

文章目录 01、Java8概述02、Java8新特性的好处03、并行流与串行流04、Lambda表达式4.1、Lambda表达式使用举例4.2、Lambda表达式语法的使用14.3、Lambda表达式语法的使用2 05、函数式(Functional)接口5.1、函数式接口的介绍5.2、Java内置的函数式接口介绍及使用举例 06、方法引…

Nodejs基于vue的个性化服装衣服穿搭搭配系统sprinboot+django+php

本个性化服装搭配系统主要根据用户数据信息&#xff0c;推荐一些适合的搭配穿搭&#xff0c;同时&#xff0c;用户也可自己扫描上传自身衣物以及输入存放位置&#xff0c;搭配后存储到“我的搭配”中&#xff0c;以便下次挑选&#xff0c;既可以节省搭配时间&#xff0c;也方便…

vue3 构建项目

一.使用vite构建&#xff1a; npm init vitelatest 项目名称 构建的项目模板 进入项目 cd 项目名称 安装项目依赖包 npm install 启动项目 npm run dev 二.使用vue脚手架构建&#xff1a; npm init vuelatest 后续基本差不多

安全防御(第六次作业)

攻击可能只是一个点&#xff0c; 防御需要全方面进行 IAE引擎 DFI和DPI技术 --- 深度检测技术 DPI --- 深度包检测技术 --- 主要针对完整的数据包&#xff08;数据包分片&#xff0c;分段需要重组&#xff09; &#xff0c;之后对 数据包的内容进行识别。&#xff08;应用层&a…

mock工具whistle使用笔记

1、下载安装地址&#xff1a;关于whistle GitBook 安装完后&#xff0c;用本地的ip&#xff1a;设置的端口就可以反问&#xff0c;端口默认的8899&#xff0c;可以自定义 2、抓包https&#xff1a; &#xff08;1&#xff09;打开https &#xff08;2&#xff09;下载证书&…

从8.8到9.9,涨价的库迪还能守住牌局吗?

作者 | 辰纹 来源 | 洞见新研社 历经超半年的9.9元活动后&#xff0c;瑞幸不仅牢牢守稳盈利态势&#xff0c;还一举创造了新的神话——中国地区年收入首超星巴克。 根据瑞幸咖啡发布的截至12月31日的2023年第四季度及全年财报。第四季度&#xff0c;瑞幸咖啡净营收为70.6亿元…

Talk|上海交通大学晋嘉睿:序列建模技术在推荐系统中的应用

本期为TechBeat人工智能社区第574期线上Talk。 北京时间2月28日(周三)20:00&#xff0c;上海交通大学博士生—晋嘉睿的Talk已准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “序列建模技术在推荐系统中的应用”&#xff0c;系统地介绍了他们在序列数据的建…

C++数据结构与算法——二叉搜索树的属性

C第二阶段——数据结构和算法&#xff0c;之前学过一点点数据结构&#xff0c;当时是基于Python来学习的&#xff0c;现在基于C查漏补缺&#xff0c;尤其是树的部分。这一部分计划一个月&#xff0c;主要利用代码随想录来学习&#xff0c;刷题使用力扣网站&#xff0c;不定时更…

【数据库管理系统】Mysql 8.0.36入门级安装

下载地址 官方网址&#xff1a;MySQL 注意事项 建议不要安装最新版本&#xff0c;一般找mysql5.0或mysql8.0系列版本即可&#xff1b;mysq1官网有.zip和.msi两种安装形式&#xff1b;zip是压缩包&#xff0c;直接解压缩以后使用的&#xff0c;需要自己配置各种东西&#xff…

用按位或、按位与取反实现权限的增减

一、介绍&#xff1a; 在Linux操作系统中&#xff1a; r -4&#xff1a;可读权限 w -2&#xff1a;可写权限 x -1&#xff1a;可执行权限 问题1&#xff1a;三个权限为1,2,4&#xff0c;分别对应:2^0,2^1,2^2&#xff0c;为什么要用8进制表示用户的文件权限&#xff1f; …

Java毕业设计 基于SpringBoot vue 社区团购系统

Java毕业设计 基于SpringBoot vue 社区团购系统 SpringBoot vue 社区团购系统 功能介绍 前端用户: 首页 图片轮播 商品信息 商品分类展示 搜索 商品详情 点我收藏 添加到购物车 立即购买 我要开团 去参团 评论 公告资讯 资讯详情 登录 注册 个人中心 更新信息 点我充值 我的订…

三、《任务列表案例》前端程序搭建和运行

本章概要 整合案例介绍和接口分析 案例功能预览接口分析 前端工程导入 前端环境搭建导入前端程序 启动测试 3.1 整合案例介绍和接口分析 3.1.1 案例功能预览 3.1.2 接口分析 学习计划分页查询 /* 需求说明查询全部数据页数据 请求urischedule/{pageSize}/{currentPage} 请…

、JMETER与它的组件们

os进程取样器 这个取样器可以让jmeter直接调用python写的测试数据 这样就可以调用python写的测试数据给到jmeter进行调用 注意&#xff1a;1建议python返回转json格式dumps一下&#xff1b;2py文件中需要把结果打印出来&#xff0c;可以不用函数直接编写 传到jmeter之后可以用…

【嵌入式学习】网络编程day0229

一、思维导图 二、练习 TCP通信 服务器 #include <myhead.h> #define SER_IP "192.168.126.42" #define SER_PORT 8888 int main(int argc, const char *argv[]) {int wfd-1;//创建套接字if((wfdsocket(AF_INET,SOCK_STREAM,0))-1){perror("error"…

Nginx多次代理后获取真实的用户IP访问地址

需求&#xff1a;记录用户操作记录&#xff0c;类似如下表格的这样 PS: 注意无论你的服务是Http访问还是Https 访问的都是可以的&#xff0c;我们服务之前是客户只给开放了一个端口&#xff0c;但是既要支持https又要支持http协议&#xff0c;nginx 是可以通过stream 模块配置双…

设计模式-结构模式-装饰模式

装饰模式&#xff08;Decorator Pattern&#xff09;&#xff1a;动态地给一个对象增加一些额外的职责&#xff0c;就增加对象功能来说&#xff0c;装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。 //首先&#xff0c;定义一个组件接口&#xff1a; public in…

【Python笔记-设计模式】策略模式

一、说明 策略模式是一种行为设计模式&#xff0c;它定义了一系列算法&#xff0c;将每个算法封装起来&#xff0c;并使它们可以互相替换。 (一) 解决问题 在需要根据不同情况选择不同算法或策略&#xff0c;规避不断开发新需求后&#xff0c;代码变得非常臃肿难以维护管理。…

python实现常见一元随机变量的概率分布

一. 随机变量 随机变量是一个从样本空间 Ω \Omega Ω到实数空间 R R R的函数&#xff0c;比如随机变量 X X X可以表示投骰子的点数。随机变量一般可以分为两类&#xff1a; 离散型随机变量&#xff1a;随机变量的取值为有限个。连续型随机变量&#xff1a;随机变量的取值是连…

VSCode上搭建C/C++开发环境(vscode配置c/c++环境)Windows系统---保姆级教程

引言劝退 VSCode&#xff0c;全称为Visual Studio Code&#xff0c;是由微软开发的一款轻量级&#xff0c;跨平台的代码编辑器。大家能来搜用VSCode配置c/c&#xff0c;想必也知道VSCode的强大&#xff0c;可以手握一个VSCode同时编写如C&#xff0c;C&#xff0c;C#&#xff…

网神 SecGate 3600 防火墙 sys_export_conf_local_save 文件读取漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…