Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍自定义Dialog组件的常用方法及灵活运用。

在之前的文章中笔者已经为大家展示了默认Dialog组件的使用方法,虽然内置组件支持对数据的输入,但有时候我们需要一次性输入多个数据,此时如果之使用默认模态对话框似乎不太够用,此时我们需要自己创建一个自定义对话框,需要说明的是此类对话框也是一种窗体,所以可以在其上面放置任何通用组件,以实现更多复杂的开发需求。

自定义对话框需要解决的问题是,如何让父窗体与子窗体进行数据交换,要实现数据的交换有两种方式,第一种方式是通过动态加载模态对话框,当用户点击确定后通过GetValue()来拿到数据,而第二种方式则是通过发送信号的方式将数据投递给父窗体,这两种方式都可以,读者可根据自身需求来选择不同的通信方式。

1.1 使用模态对话框传值

首先我们需要创建一个自定义对话框,在Qt中创建对话框很容易,具体创建流程如下所示:

  • 选择项目 -> AddNew -> QT -> Qt设计师界面类 -> 选择DialogWithoutButtons -> 命名为Dialog保存

此时直接点击下一步按钮,并选中Forms/dialog.ui界面编辑菜单,在编辑栏中我们分别增加一个LineEdit编辑框,以及两个PushButton按钮组件,将第一个组件命名为BtnOk将第二个组件命名为BtnCancel,界面如下所示;

当做完页面布局后,其次我们还需要在Dialog.ui组件上增加两个信号,分别是点击关闭,并将信号关联到两个槽函数上,其信号应该写成如下图所示。

如上图,accept()QDialog 类的一个公共槽函数。调用这个槽函数会触发对话框的接受(accept)操作,通常用于模拟用户点击对话框的“确定”按钮。同样的reject() 也是 QDialog 类的一个公共槽函数。调用这个槽函数会触发对话框的拒绝(reject)操作,通常用于模拟用户点击对话框的“取消”按钮。

接着我们点开模态对话框的dialog.cpp对话框类,其类内需要定义两个成员函数,它们的功能如下:

  • 第一个 GetValue() 用来获取当前编辑框内的数据并将数据返回给父窗体。
  • 第二个 SetValue() 用来接收传入的参数,并将此参数设置到自身窗体中的编辑框内。
#include "dialog.h"
#include "ui_dialog.h" Dialog::Dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Dialog)
{
ui->setupUi(this);
} // 用于MainWindow获取编辑框中的数据
QString Dialog::GetValue()
{
return ui->lineEdit->text();
} // 用于设置当前编辑框中的数据为MainWindow
void Dialog::SetValue(QString x)
{
ui->lineEdit->setText(x);
} Dialog::~Dialog()
{
delete ui;
}

接着我们来看一下MainWindow函数中是如何接收参数的,对于主窗体来说,当用户点击on_pushButton_clicked()按钮时,我们需要动态将自己创建的Dialog加载,读取出主窗体编辑框内的值并设置到子窗体内,当用户按下QDialog::Accepted时则是获取子窗体内的值,此时通过调用ptr->GetValue()子窗体的成员函数来返回一个字符串,并将其设置到父窗体的编辑框内,主函数代码如下所示;

// 首先要包含Dialog对话框类
#include "dialog.h" #include <iostream>
#include <QDialog> MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->lineEdit->setEnabled(false);
ui->lineEdit->setText("hello lyshark");
} MainWindow::~MainWindow()
{
delete ui;
} // 按钮点击后执行
void MainWindow::on_pushButton_clicked()
{
// 创建模态对话框
Dialog *ptr = new Dialog(this); // 创建一个对话框
Qt::WindowFlags flags = ptr->windowFlags(); // 需要获取返回值
ptr->setWindowFlags(flags | Qt::MSWindowsFixedSizeDialogHint); // 设置对话框固定大小 // 读取MainWindows参数并设置到Dialog
QString item = ui->lineEdit->text();
ptr->SetValue(item); int ref = ptr->exec(); // 以模态方式显示对话框
if (ref==QDialog::Accepted) // OK键被按下,对话框关闭
{
// 当BtnOk被按下时,则设置对话框中的数据
QString the_value = ptr->GetValue();
std::cout << "value = " << the_value.toStdString().data() << std::endl;
ui->lineEdit->setText(the_value);
} // 删除释放对话框句柄
delete ptr;
}

至此就实现了参数的子窗体传递到父窗体,如下图所示;

2.1 使用信号传值

对于信号传值,我们需要在dialog.h头文件中增加sendText()信号,以及on_pushButton_clicked()槽函数的声明部分,如下所示;

// 定义信号(信号只需声明无需实现)
signals:
void sendText(QString str);
private slots:
void on_pushButton_clicked();

而在dialog.cpp实现部分,我们首先需要将子窗体中的按钮组件绑定到onBtnClick()槽函数上面,当需要发送数据时直接通过调用emit sendText触发信号,并携带子窗体中send_data的数据;

#include "dialog.h"
#include "ui_dialog.h" Dialog::Dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Dialog)
{
ui->setupUi(this); // 连接pushButton到onBtnClick上
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(onBtnClick()));
} Dialog::~Dialog()
{
delete ui;
} // 发送信号到MainWindow
void Dialog::on_pushButton_clicked()
{
QString send_data = ui->lineEdit->text();
emit sendText(send_data);
}

接着是在mainwindow.h头文件定义中,新增槽函数receiveMsg()函数用来接收信号的传值。

private slots:
// 定义槽函数
void receiveMsg(QString str);
void on_pushButton_clicked();

mainwindow.cpp实现部分,接收到信号后的槽函数receiveMsg其内部可以直接将参数设置到父类窗口的lineEdit组件上,而当on_pushButton_clicked按钮被点击是,我们只需要加载自己的子窗体,并Connect链接槽函数receiveMsg上面,当做完这一切之后,再通过subwindow->show()让子窗体显示出来。

#include "mainwindow.h"
#include "ui_mainwindow.h" #include "dialog.h"
#include <QDialog> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->lineEdit->setEnabled(false);
} // 接收信号并设置到LineEdit上
void MainWindow::receiveMsg(QString str)
{
ui->lineEdit->setText(str);
} MainWindow::~MainWindow()
{
delete ui;
} void MainWindow::on_pushButton_clicked()
{
Dialog *subwindow = new Dialog(this);
// 当收到sendText信号时使用receiveMsg槽函数处理
connect(subwindow, SIGNAL(sendText(QString)), this, SLOT(receiveMsg(QString)));
subwindow->show();
}

当然,此类对话框是非模态的,读者可以拖动父对话框,而由于是信号控制,所以当发送参数到父窗体后,子窗体并不会立即关闭,如下图所示;

完整案例下载

C++ Qt开发:自定义Dialog对话框组件的更多相关文章

  1. C/C++ Qt 自定义Dialog对话框组件应用

    在上一篇博文 <C/C++ Qt 标准Dialog对话框组件应用> 中我给大家演示了如何使用Qt中内置的标准对话框组件实现基本的数据输入功能. 但有时候我们需要一次性修改多个数据,使用默认 ...

  2. Android中制作自定义dialog对话框的实例

    http://www.jb51.net/article/83319.htm   这篇文章主要介绍了Android中制作自定义dialog对话框的实例分享,安卓自带的Dialog显然不够用,因而我们要继 ...

  3. 第二百零四节,jQuery EasyUI,Dialog(对话框)组件

    jQuery EasyUI,Dialog(对话框)组件 学习要点: 1.加载方式 2.属性列表 3.事件列表 4.方法列表 本节课重点了解EasyUI中Dialog(窗口)组件的使用方法,这个组件依赖 ...

  4. Taro自定义Modal对话框组件|taro仿微信、android弹窗

    基于Taro多端实践TaroPop:自定义模态框|dialog对话框|msg消息框|Toast提示 taro自定义弹出框支持编译到多端H5/小程序/ReactNative,还可以自定义弹窗类型/弹窗样 ...

  5. Android自定义 Dialog 对话框

    Android自定义Dialoghttp://www.cnblogs.com/and_he/archive/2011/09/16/2178716.html Android使用自定义AlertDialo ...

  6. C/C++ Qt Dialog 对话框组件应用

    在Qt中对话框分为两种形式,一种是标准对话框,另一种则是自定义对话框,在一般开发过程中标准对话框使用是最多的了,标准对话框一般包括 QMessageBox,QInputDialog,QFileDial ...

  7. Dialog( 对话框) 组件

    一. 加载方式//class 加载方式<div class="easyui-dialog" title="My Dialog"style="wi ...

  8. 【开发】Dialog 对话框

    提示:Dialog 继承自 Panel,有大量的方法在 Panel 中已被定义,可以复用. Dialog API:http://www.jeasyui.net/plugins/181.html Pan ...

  9. Java Swing 自定义Dialog确认对话框

    Java Swing 自定义Dialog 需求:当点击JFrame窗口的关闭按钮时,弹框询问是否确定关闭窗口,如果是则关闭程序,否就让弹框消失什么也不做(使用Dialog). 分析:虽然Java提供了 ...

  10. vue3系列:vue3.0自定义弹框组件V3Popup|vue3.x手机端弹框组件

    基于Vue3.0开发的轻量级手机端弹框组件V3Popup. 之前有分享一个vue2.x移动端弹框组件,今天给大家带来的是Vue3实现自定义弹框组件. V3Popup 基于vue3.x实现的移动端弹出框 ...

随机推荐

  1. Elasticsearch之环境搭建

    一.安装 elasticsearch -- 拉取镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:8.9.1 -- 创建 doc ...

  2. Python Flask 上下文管理源码分析

    Python Flask 上下文管理源码分析 前言 Flask 上下文管理可以说是 Flask 非常具有特色的设计,它总共可分为 2 个大的方向: 应用上下文管理:通过 current_app 即可拿 ...

  3. redis基本数据类型 List

    127.0.0.1:6379> LPUSH test a (integer) 1 127.0.0.1:6379> LPUSH test b (integer) 2 127.0.0.1:63 ...

  4. modbus转profinet网关连接ABB变频器在博图程序案例

    modbus转profinet网关连接ABB变频器在博图程序案例 在博图里PLC无需编程利用兴达易控modbus转Profinet网关将ABB变频器接入到西门子网络中,用到设备为西门子1200PLC, ...

  5. 4.Autofac依赖注入初使用

    前面几篇文章只是初步搭建项目结构,那到底能否运行呢?(能是肯定的啦) 毕竟咱都NetCore了,所以依赖注入要搞起来.专业的解释我就不多说了,很多博客文章说的很详细(其实是我忘了那些术语怎么讲). 按 ...

  6. Shell 文件或目录操作符(-e、-d、-f、-r、-w、-x)

    操作符 操作符 含义-e 判断对象是否存在(Exist),若存在则结果为真-d 判断对象是否为目录(Directory),是则为真-f 判断对象是否为一般文件(File),是则为真-r 判断对象是否有 ...

  7. 《美英报刊阅读教程(中级精选本)(第五版)》 ISBN: 9787301306864

    作者: 端木义万 著 出版社:  北京大学出版社 出版时间:  2019-09 版次:  7 ISBN:  9787301306864 定价:  69.00 装帧:  平装 开本:  16开 纸张:  ...

  8. vue 基于原生动画的自动滚动表格

    前言 公司展示大屏需要写滚动表格,通过滚动播放数据,自己随便摸了一个基于动画的自动滚动表格 原理 根据每行的大小和设置的每行滚动时间设置滚动位置,动态添加动画,并把数组第一项移动到最后一项,并订阅该动 ...

  9. Go包介绍与初始化:搞清Go程序的执行次序

    Go包介绍与初始化:搞清Go程序的执行次序 目录 Go包介绍与初始化:搞清Go程序的执行次序 一.main.main 函数:Go 应用的入口函数 1.1 main.main 函数 1.2 main.m ...

  10. H5-geolocation学习

    geolocation--定位 PC--IP地址 精度比较低 IP库 Chrome -> Google 手机--GPS window.navigator.geolocation 单次 getCu ...