【qt】自定义对话框

自定义对话框

一.自定义对话框的使用

1.应用场景

像我们前面一般就是只有一个主窗口,或者是只有一些简单的对话框,有的时候我们需要多窗口操作,并且需要一下高级的对话框的时候,我们就可以自定义来达到我们的需求。

2.项目效果

纸上得来终觉浅,咱们还是来继续跟着项目来


咱们有3个功能,我们就自定义3个对话框,并能完成相应的功能,OK,咋们开始吧!

3.界面拖放

这个我就不讲了,需要蔬菜的可以dd我

这里是把tableView设置为了中心组件

4.模型和视图的设置

还记得我们原来在tableView 里面讲的的模型和视图嘛,现在我们来添加模型和设置视图。

哈哈,给你们截图,不给你们代码,自己敲,涨涨记性。

创建模型,并为视图设置模型!

运行结果:

但是很丑咯,只显示了一部分,还需要我手动放大,才能显示全,我们可以对表头的视图进行设置。

运行结果:

现在,表头就可以自动的拉伸,非常的银信,哈哈.

5.action功能实现

对咱们的action使用转到槽,接下来就是重点了.好好看,好好学!

二.自定义对话框的创建

1.设置对话框界面

选择不带按钮的对话框

类名,你自己随便起:

OK,现在就开始来设计我们的对话框,

这里可以设置按钮的图标哦.

设计完我们的对话框设计

2.创建对话框

首先在mainwindow.cpp 包含咱们的头文件

cpp 复制代码
void MainWindow::on_actionResize_triggered()
{
    DialogResize*dialogResize=new DialogResize(this);    
}

这样我们自定义的对话框就创建好了!

三.对话框的功能与样式实现

1.对话框数据的交换

首先我们需要对话框拿到我们主窗口默认的行列数.

所以我们需要在dialogresize.h 设置公有接口.

具体的实现:

现在就可以进行使用了

cpp 复制代码
void MainWindow::on_actionResize_triggered()
{
    DialogResize*dialogResize=new DialogResize(this);
    dialogResize->setCol(model->columnCount());
    dialogResize->setRow(model->rowCount());
    
}

但是现在我们点击这个按钮无效,因为对话框还没有进行显示!

2.对话框的显示

cpp 复制代码
dialogResize->exec();//模态方式进行显示,就是必须要处理完对话框,才能对主窗口进行操作

运行结果:

3.设置对话框的特性

4.完成按钮的功能

现在我们点对话框的确定和取消都是没有用的.

对按钮转到槽

cpp 复制代码
void DialogResize::on_pushButtonOK_clicked()
{
    //关闭对话框 并返回一个QDialog::Accepted的枚举值
    accept();
}

void DialogResize::on_pushButtonCancel_clicked()
{
    //关闭对话框 并返回一个QDialog::Reject的枚举值
    reject();
}

那咱们这个返回值由谁来接收呢?答案就是对话框显示的接口

cpp 复制代码
int ret=dialogResize->exec();//模态方式进行显示,就是必须要处理完对话框,才能对主窗口进行操作
    if(ret==QDialog::Accepted)
    {
        //如果点击了确定,咱们就对主窗口的行列进行设置
        
    }

很明显,咱们现在需要去拿到对话框里面的数据,用面向对象的思想,去对话框里面设置接口.

具体实现:

cpp 复制代码
int DialogResize::getRowCount()
{
    return ui->spinBoxRow->value();
}

int DialogResize::getColCount()
{
    return ui->spinBoxCol->value();
}

现在就可以拿到数据,并对模型进行设置了

cpp 复制代码
void MainWindow::on_actionResize_triggered()
{
    DialogResize*dialogResize=new DialogResize(this);
    dialogResize->setCol(model->columnCount());
    dialogResize->setRow(model->rowCount());
    //对话框固定,不能对对话框进行拉伸
    dialogResize->setWindowFlags(dialogResize->windowFlags()|Qt::MSWindowsFixedSizeDialogHint);

    int ret=dialogResize->exec();//模态方式进行显示,就是必须要处理完对话框,才能对主窗口进行操作
    if(ret==QDialog::Accepted)
    {
        //如果点击了确定,咱们就对主窗口的行列进行设置
        int rows=dialogResize->getRowCount();
        int cols=dialogResize->getColCount();
        
        model->setRowCount(rows);
        model->setColumnCount(cols);
    }
    //因为每次打开都new了一个窗口,需要我们手动删除
    delete dialogResize;//每次我们要手动关闭
}

运行结果:

OK,就变成了10*10了

这样一个功能就基本把对话框的套路讲清楚了,接下来还有两个对话框,多注意一下细节就OK了.

四.编辑表头的对话框

1.对话框界面设计

2.创建对话框

这次我们在mainwindow.h 中添加我们的对话框

添加私有成员

然后开始创建;

cpp 复制代码
void MainWindow::on_actionHeader_triggered()
{
    //只创建一次,对话框可以重复使用
    if(dialogHeader==NULL)
    {
        dialogHeader=new DialogHeader(this);//设置父窗口this,有个好处就是当我们关闭主窗口的时候,会调用对话框的析构函数
    }
}

3.为对话框添加模型

创建模型和视图设置模型:

4.对话框功能实现

我们需要获取表头的值来初始化对话框的视图模型

dialogHeader.h

实现:

cpp 复制代码
void DialogHeader::setList(const QStringList &list)
{
    model->setStringList(list);
}

对按钮还是用转到槽:

cpp 复制代码
void DialogHeader::on_pushButtonOK_clicked()
{
    accept();
}

void DialogHeader::on_pushButtonCancel_clicked()
{
    reject();
}

我们还需要对话框的模型视图来设置主窗口的表头信息.

实现:

cpp 复制代码
void MainWindow::on_actionHeader_triggered()
{
    //只创建一次,对话框可以重复使用
    if(dialogHeader==NULL)
    {
        dialogHeader=new DialogHeader(this);//设置父窗口this,有个好处就是当我们关闭主窗口的时候,会调用对话框的析构函数
    }
    
    //将表头的数据设置到ListView视图中
    QStringList list;
    for(int i=0;i<model->columnCount();i++)
    {
        list.append(model->headerData(i,Qt::Horizontal).toString());
    }
    dialogHeader->setList(list);
    int ret=dialogHeader->exec();
    if(ret==QDialog::Accepted)
    {
    //设置水平表头的信息
        model->setHorizontalHeaderLabels(dialogHeader->getList());
    }
}

运行结果:

四.单元格的对话框

基本都差不多,我只重点的讲一下不同的地方!刚刚我们都玩的模态的,现在我们来玩玩非模态的,就是主窗口和父窗口可以同时进行操作.

UI设计:

mainwindow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QStandardItemModel>
#include <QItemSelectionModel>
#include "dialogheader.h"
#include "dialoglocation.h"//定位单元格头文件

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    void setEnable(bool flag);
    void setCell(int row,int col,QString text);//设置主窗口的单元格信息

private slots:
    void on_actionResize_triggered();

    void on_actionHeader_triggered();

    void on_actionLocation_triggered();

private:
    Ui::MainWindow *ui;

    QStandardItemModel*model;
    QItemSelectionModel*selectionModel;

    DialogHeader*dialogHeader=NULL;
    DialogLocation*dialogLocation=NULL;//定位单元格
};
#endif // MAINWINDOW_H

mainwindow.cpp

cpp 复制代码
void MainWindow::on_actionLocation_triggered()
{
    dialogLocation=new DialogLocation(this);
    //当关闭对话框时, 会自动的回收内存,就不用delete去删除了
    dialogLocation->setAttribute(Qt::WA_DeleteOnClose);
    //对话框一直在表面 参数为原有的属性加新的属性
    dialogLocation->setWindowFlags(dialogLocation->windowFlags()|Qt::WindowStaysOnTopHint);
    dialogLocation->setMaxRowCol(model->rowCount()-1,model->columnCount()-1);

    auto index=selectionModel->currentIndex();
    dialogLocation->setCurrenRowCol(index.row(),index.column());

    dialogLocation->show();//模态方式进行显示,点击按钮是不会关闭的,同时主窗口也可以继续操作
}

dialoglocation.h

cpp 复制代码
#ifndef DIALOGLOCATION_H
#define DIALOGLOCATION_H

#include <QDialog>

namespace Ui {
class DialogLocation;
}

class DialogLocation : public QDialog
{
    Q_OBJECT

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

    void setMaxRowCol(int rowMax,int colMax);
    void setCurrenRowCol(int row,int col);
private:
//对话框关闭和打开时自动调用
    void closeEvent(QCloseEvent *event);
    void showEvent(QShowEvent*event);

private slots:
    void on_pushButtonOk_clicked();

    void on_pushButtonCancel_clicked();

private:
    Ui::DialogLocation *ui;
};

#endif // DIALOGLOCATION_H

dialogLocation.cpp

cpp 复制代码
#include "dialoglocation.h"
#include "ui_dialoglocation.h"
#include "mainwindow.h"

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

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

void DialogLocation::setMaxRowCol(int rowMax, int colMax)
{
    ui->spinBoxRow->setMaximum(rowMax);
    ui->spinBoxCol->setMaximum(colMax);
}

void DialogLocation::setCurrenRowCol(int row, int col)
{
    ui->spinBoxCol->setValue(col);
    ui->spinBoxRow->setValue(row);
}

void DialogLocation::on_pushButtonOk_clicked()
{
    MainWindow*mainWindow=(MainWindow*)parentWidget();
    mainWindow->setCell(ui->spinBoxRow->value(),ui->spinBoxCol->value(),ui->lineEdit->text());
    if(ui->checkBoxCol->isChecked())
    {
        ui->spinBoxCol->setValue(ui->spinBoxCol->value()+1);
    }
    if(ui->checkBoxRow->isChecked())
    {
        ui->spinBoxRow->setValue(ui->spinBoxRow->value()+1);
    }
}

void DialogLocation::on_pushButtonCancel_clicked()
{
    close();
}
void DialogLocation::closeEvent(QCloseEvent *event)
{
    MainWindow*mainWindow=(MainWindow*)parentWidget();
    mainWindow->setEnable(true);
}
void DialogLocation::showEvent(QShowEvent*event)
{
    MainWindow*mainWindow=(MainWindow*)parentWidget();
    mainWindow->setEnable(false);
}

运行结果:

确实类比较多,跳来跳去,不好截图,所以我就都截下来了,有不懂的可以问我.

五.总结

对于自定义的对话框,也是有模板套路可寻的,注意的是数据之间的交互,面向对象的思想!

确实我感觉我截的有点乱,来给你们一个我梳理的思维导图吧!

是不是很爱你呀!哈哈.

两岸猿声啼不住,轻舟已过万重山

相关推荐
凡人叶枫6 分钟前
Effective C++ 条款22:将成员变量声明为 private
linux·开发语言·c++
Qt程序员12 分钟前
掌握 Linux 内核调度:从原理到实现(进程篇)
java·开发语言
code bean17 分钟前
【LangChain】检索器完全指南:从向量检索到生产级 RAG 架构
java·开发语言·微服务
LabVIEW开发36 分钟前
LabVIEW + MATLAB 混合编程:爆炸场测试数据精准采集方案
开发语言·matlab·labview
嵌入式协会202407236 分钟前
(已解决)MinIO python 获取预签名出现forbidden、errornetwork等错误
java·开发语言·python
宸丶一44 分钟前
Day 14:任务追踪 - 让 Agent 拥有项目管理能力
开发语言·python
小短腿的代码世界1 小时前
Qt行情协议解析与二进制编解码优化:从FIX到自定义协议的全链路架构
开发语言·qt·架构
skylar01 小时前
小白1分钟安装flash-attn
开发语言·python
默子昂1 小时前
ollama 自定义ui
开发语言·python·ui
袁小皮皮不皮1 小时前
1.HCIP BFD 学习笔记(优化版)
服务器·网络·笔记·网络协议·学习·智能路由器·ip