4.完成按钮的功能
现在我们点对话框的确定和取消都是没有用的.
对按钮转到槽
void DialogResize::on_pushButtonOK_clicked() { //关闭对话框 并返回一个QDialog::Accepted的枚举值 accept(); } void DialogResize::on_pushButtonCancel_clicked() { //关闭对话框 并返回一个QDialog::Reject的枚举值 reject(); }
那咱们这个返回值由谁来接收呢?答案就是对话框显示的接口
int ret=dialogResize->exec();//模态方式进行显示,就是必须要处理完对话框,才能对主窗口进行操作 if(ret==QDialog::Accepted) { //如果点击了确定,咱们就对主窗口的行列进行设置 }
很明显,咱们现在需要去拿到对话框里面的数据,用面向对象的思想,去对话框里面设置接口.
具体实现:
int DialogResize::getRowCount() { return ui->spinBoxRow->value(); } int DialogResize::getColCount() { return ui->spinBoxCol->value(); }
现在就可以拿到数据,并对模型进行设置了
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中添加我们的对话框
添加私有成员
然后开始创建;
void MainWindow::on_actionHeader_triggered() { //只创建一次,对话框可以重复使用 if(dialogHeader==NULL) { dialogHeader=new DialogHeader(this);//设置父窗口this,有个好处就是当我们关闭主窗口的时候,会调用对话框的析构函数 } }
3.为对话框添加模型
创建模型和视图设置模型:
4.对话框功能实现
我们需要获取表头的值来初始化对话框的视图模型
在dialogHeader.h中
实现:
void DialogHeader::setList(const QStringList &list) { model->setStringList(list); }
对按钮还是用转到槽:
void DialogHeader::on_pushButtonOK_clicked() { accept(); } void DialogHeader::on_pushButtonCancel_clicked() { reject(); }
我们还需要对话框的模型视图来设置主窗口的表头信息.
实现:
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中
#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中
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中
#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中
#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); }
运行结果:
确实类比较多,跳来跳去,不好截图,所以我就都截下来了,有不懂的可以问我.
五.总结
对于自定义的对话框,也是有模板套路可寻的,注意的是数据之间的交互,面向对象的思想!
确实我感觉我截的有点乱,来给你们一个我梳理的思维导图吧!
是不是很爱你呀!哈哈.
两岸猿声啼不住,轻舟已过万重山