自定义对话框
一.自定义对话框的使用
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);
}
运行结果:
确实类比较多,跳来跳去,不好截图,所以我就都截下来了,有不懂的可以问我.
五.总结
对于自定义的对话框,也是有模板套路可寻的,注意的是数据之间的交互,面向对象的思想!
确实我感觉我截的有点乱,来给你们一个我梳理的思维导图吧!
是不是很爱你呀!哈哈.
两岸猿声啼不住,轻舟已过万重山