【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);
}

运行结果:

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

五.总结

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

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

是不是很爱你呀!哈哈.

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

相关推荐
IT猿手4 分钟前
最新高性能多目标优化算法:多目标麋鹿优化算法(MOEHO)求解TP1-TP10及工程应用---盘式制动器设计,提供完整MATLAB代码
开发语言·深度学习·算法·机器学习·matlab·多目标算法
单片机学习之路8 分钟前
【C语言】结构
c语言·开发语言·stm32·单片机·51单片机
thesky1234569 分钟前
活着就好20241224
学习·算法
ALISHENGYA14 分钟前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(实战项目二)
数据结构·c++·算法
蜗牛hb17 分钟前
VMware Workstation虚拟机网络模式
开发语言·学习·php
arong_xu28 分钟前
现代C++锁介绍
c++·多线程·mutex
汤姆和杰瑞在瑞士吃糯米粑粑32 分钟前
【C++学习篇】AVL树
开发语言·c++·学习
Biomamba生信基地40 分钟前
R语言基础| 功效分析
开发语言·python·r语言·医药
DARLING Zero two♡40 分钟前
【优选算法】Pointer-Slice:双指针的算法切片(下)
java·数据结构·c++·算法·leetcode
手可摘星河42 分钟前
php中 cli和cgi的区别
开发语言·php