学习《QT5.9 c++ 开发指南》第6章 自定义的对话框及其调用

       今天看一下第6章,第二节,这个例子比较简单的,这边只是简单介绍一下。有关界面布局与基本的操作这里就不细说了,下面让我们开始吧!

       本例子基于QMainWindow,创建的ui界面,文件取名6_2QDialogLocate。

       首先将准备好的图片资源放到建好的新建的工程目录下,图片资源如下:

       链接:工程图片    提取码:6yju 

     


       在工程中,添加,资源文件,取名为res. 添加完成后如下图:

现在开始编辑,菜单项,与界面布局,主界面如下图:

     

菜单部分如下:

主窗口创建成功了,现在开始创建,另外3个窗口,选择“file ”→“new file or project”,选择“Qt Designer form Class”,."Dialog without Buttons",取名:QWDialogSize 。同理在创建QWDialogHeaders , QWDialogLocate,两个类。

1.创建QWDialogSize,界面布局如下图:

添加对应的槽函数:

      点击确定按钮,会关闭对话框(不删除),并返回QDialog::Accepted 做为exec() 的返回值,取消则执行reject(),关闭对话框,并返回QDialog::Rejected. 做为返回值。

     qwdialogsize.h   中代码如下:

#ifndef QWDIALOGSIZE_H
#define QWDIALOGSIZE_H

#include <QDialog>

namespace Ui {
class QWDialogSize;
}

class QWDialogSize : public QDialog
{
    Q_OBJECT

public:
    explicit QWDialogSize(QWidget *parent = nullptr);
    ~QWDialogSize();
    
    int rowCount();//获取对话框输入的行数
    int columnCount();//获取对话框输入的列数
    void  setRowColumn(int row, int column); //初始对话框上两个SpinBox的值

private:
    Ui::QWDialogSize *ui;
};

#endif // QWDIALOGSIZE_H

qwdialogsize.cpp 文件代码如下:

#include "qwdialogsize.h"
#include "ui_qwdialogsize.h"

#include    <QMessageBox>
QWDialogSize::QWDialogSize(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::QWDialogSize)
{
    ui->setupUi(this);
}

QWDialogSize::~QWDialogSize()
{
    QMessageBox::information(this,"提示","设置表格行列数对话框被删除");
    delete ui;
}

int QWDialogSize::rowCount()
{
    return  ui->spinBoxRow->value();
}

int QWDialogSize::columnCount()
{
    return ui->spinBoxColumn->value();
}

void QWDialogSize::setRowColumn(int row, int column)
{
    ui->spinBoxRow->setValue(row);
    ui->spinBoxColumn->setValue(column);
}

2.创建QWDialogHeaders ,界面布局如下图:

qwdialogheaders.h   中代码如下:

#ifndef QWDIALOGHEADERS_H
#define QWDIALOGHEADERS_H

#include <QDialog>

#include    <QStringListModel>
namespace Ui {
class QWDialogHeaders;
}

class QWDialogHeaders : public QDialog
{
    Q_OBJECT
private:
    QStringListModel *model;

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

    void setHeaderList(QStringList& headers);
    QStringList headerList();
private:
    Ui::QWDialogHeaders *ui;
};

#endif // QWDIALOGHEADERS_H

qwdialogheaders.cpp  中代码如下:

#include "qwdialogheaders.h"
#include "ui_qwdialogheaders.h"
#include<QMessageBox>
QWDialogHeaders::QWDialogHeaders(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::QWDialogHeaders)
{
    ui->setupUi(this);
    model = new QStringListModel;
    ui->listView->setModel(model);
}

QWDialogHeaders::~QWDialogHeaders()
{
    QMessageBox::information(this,"提示","设置表格后行数对话框被删除");
    delete ui;
}

void QWDialogHeaders::setHeaderList(QStringList &headers)
{
     model->setStringList(headers);
}

QStringList QWDialogHeaders::headerList()
{
    return  model->stringList();
}

2.创建QWDialogLocate,界面布局如下图:

3. qwdialoglocate.h对应的代码:

#ifndef QWDIALOGLOCATE_H
#define QWDIALOGLOCATE_H

#include <QDialog>

namespace Ui {
class QWDialogLocate;
}

class QWDialogLocate : public QDialog
{
    Q_OBJECT
private:
    void closeEvent(QCloseEvent *event);
    void showEvent(QShowEvent *event);

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

    void    setSpinRange(int rowCount, int colCount); //设置最大值
    void    setSpinValue(int rowNo, int colNo);//设置初始值

private slots:
    void on_btnSetText_clicked();

private:
    Ui::QWDialogLocate *ui;
};

#endif // QWDIALOGLOCATE_H

对应的cpp 文件为:

#include "qwdialoglocate.h"
#include "ui_qwdialoglocate.h"
#include    <QCloseEvent>
#include    "mainwindow.h"
#include    <QMessageBox>
void QWDialogLocate::closeEvent(QCloseEvent *event)
{
    //窗口关闭事件,关闭时释放本窗口
    Q_UNUSED(event)
    MainWindow *parWind = (MainWindow*)parentWidget(); //获取父窗口指针
    parWind->setActLocateEnable(true);//使能 actTab_Locate
    parWind->setDlgLocateNull(); //将窗口指针设置为NULL
}

void QWDialogLocate::showEvent(QShowEvent *event)
{
    //窗口显示事件
    Q_UNUSED(event)
    MainWindow *parWind = (MainWindow*)parentWidget();//获取
    parWind->setActLocateEnable(false);
}

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

QWDialogLocate::~QWDialogLocate()
{
    QMessageBox::information(this,"提示","单元格定位对话框被删除");
    delete ui;
}

void QWDialogLocate::setSpinRange(int rowCount, int colCount)
{
    //设置SpinBox输入最大值
     ui->spinBoxRow->setMaximum(rowCount-1);
     ui->spinBoxColumn->setMaximum(colCount-1);
}

void QWDialogLocate::setSpinValue(int rowNo, int colNo)
{
    //设置SpinBox数值
    ui->spinBoxRow->setValue(rowNo);
    ui->spinBoxColumn->setValue(colNo);
}

void QWDialogLocate::on_btnSetText_clicked()
{
    //定位到单元格,并设置字符串
        int row=ui->spinBoxRow->value(); //行号
        int col=ui->spinBoxColumn->value();//列号

        MainWindow *parWind = (MainWindow*)parentWidget(); //获取主窗口
        parWind->setACellText(row,col,ui->edtCaption->text()); //设置单元格文字
        if (ui->chkBoxRow->isChecked()) //行增
            ui->spinBoxRow->setValue(1+ui->spinBoxRow->value());

        if (ui->chkBoxColumn->isChecked()) //列增
            ui->spinBoxColumn->setValue(1+ui->spinBoxColumn->value());
}

其中

    parWind->setActLocateEnable(true);//使能 actTab_Locate
    parWind->setDlgLocateNull(); //将窗口指针设置为NULL

对应的函数在MainWindow中有编写.

最终我们直接上MainWindow中的代码:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QStandardItemModel>
#include <QItemSelectionModel>
#include <QLabel>

#include "qwdialogsize.h"
#include "qwdialogheaders.h"
#include "qwdialoglocate.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    //用于状态栏的信息显示
    QLabel *LabCellPos;    //当前单元格行列号
    QLabel *LabCellText;   //当前单元格内容

    QStandardItemModel *theModel;//数据模型
    QItemSelectionModel *theSelection;//Item选择模型

    QWDialogHeaders *dlgSetHeaders=NULL;//设置表头文字对话框, 一次创建,exec()重复调用
    QWDialogLocate  *dlgLocate=NULL;//定位单元格对话框,show()调用,关闭时自己删除

    void closeEvent(QCloseEvent *event);//关闭窗口时间,可以询问是否退出

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

    void    setActLocateEnable(bool enable);//设置actTab_Locate的enabled属性
//    void    selectACell(int row,int column);//选择一个单元格,由dlgLocate调用
    void    setACellText(int row,int column,QString text);//设置一个单元格的内容,由dlgLocate调用
    void    setDlgLocateNull();//将dlgLocate指针设置为NULL

private slots:
    void on_currentChanged(const QModelIndex &current, const QModelIndex &previous); //手动添加

    void on_actTab_SetSize_triggered();


    void on_actTab_SetHeader_triggered();

    void on_actTab_Locate_triggered();

    void on_tableView_clicked(const QModelIndex &index);

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

对应cpp里的代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QLabel>
#include <QMessageBox>
#include <QCloseEvent>
void MainWindow::closeEvent(QCloseEvent *event)
{
    //窗口关闭时询问是否退出
    QMessageBox::StandardButton result = QMessageBox::question(this,"确认", "确定要退出本程序吗?",
                                          QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,
                                          QMessageBox::No);
    if(result == QMessageBox::Yes)
        event->accept();
    else {
        event->ignore();
    }
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    theModel = new QStandardItemModel(10,5,this);//创建数据模型
    theSelection = new QItemSelectionModel(theModel);//Item选择模型
    connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)),
            this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));
     //为tableView设置数据模型
    ui->tableView->setModel(theModel); //设置数据模型
    ui->tableView->setSelectionModel(theSelection); //设置选择模型

    setCentralWidget(ui->tableView);
    //创建状态栏组件
    LabCellPos = new QLabel("当前单元格:",this);
    LabCellPos->setMinimumWidth(150);
    LabCellPos->setAlignment(Qt::AlignHCenter);


    LabCellText = new QLabel("单元格内容:",this);
    LabCellText->setMinimumWidth(200);

    ui->statusBar->addWidget(LabCellPos);
    ui->statusBar->addWidget(LabCellText);

}

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

void MainWindow::setActLocateEnable(bool enable)
{
    ui->actTab_Locate->setEnabled(enable);
}

void MainWindow::setACellText(int row, int column, QString text)
{
    //定位到单元格,并设置字符串
    QModelIndex index=theModel->index(row,column);//获取模型索引
    theSelection->clearSelection(); //清除现有选择
    theSelection->setCurrentIndex(index,QItemSelectionModel::Select); //定位到单元格
    theModel->setData(index,text,Qt::DisplayRole);//设置单元格字符串
}

void MainWindow::setDlgLocateNull()
{
    dlgLocate=NULL;
}

void MainWindow::on_currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
    Q_UNUSED(previous)
    if(current.isValid())//当前模型索引有效
    {
        LabCellPos->setText(QString::asprintf("当前单元格:%d行,%d列",
                                 current.row(),current.column()));//显示模型索引的行和列号
        QStandardItem   *aItem;
        aItem=theModel->itemFromIndex(current); //从模型索引获得Item
        this->LabCellText->setText("单元格内容:"+aItem->text());
    }
}

void MainWindow::on_actTab_SetSize_triggered()
{
   //模态对话框,动态创建,用过后删除
    QWDialogSize * dlgTableSize = new QWDialogSize(this);//创建对话框
    //对话框关闭时自动删除对话框对象,用于不需要读取返回值的对话框
    //如果需要获取对话框的返回值,不能设置该属性,可以在调用完对话框后删除对话框
    Qt::WindowFlags flage = dlgTableSize->windowFlags();//获取标识
    dlgTableSize->setWindowFlags(flage | Qt::MSWindowsFixedSizeDialogHint);//设定固定的格式

    dlgTableSize->setRowColumn(theModel->rowCount(),theModel->columnCount()); //对话框数据初始化

    int ret = dlgTableSize->exec(); //以模态方式显示对话框,用户关闭对话框时返回 DialogCode值
    if(ret == QDialog::Accepted)
    {//OK键被按下,获取对话框上的输入,设置行数和列数
        int row = dlgTableSize->rowCount();
        int column = dlgTableSize->columnCount();
        theModel->setRowCount(row);
        theModel->setColumnCount(column);
    }
    delete  dlgTableSize;
}

void MainWindow::on_actTab_SetHeader_triggered()
{
     //一次创建,多次调用,对话框关闭时只是隐藏
    if (dlgSetHeaders==NULL) //如果对象没有被创建过,就创建对象
        dlgSetHeaders = new QWDialogHeaders(this);
    if (dlgSetHeaders->headerList().count()!=theModel->columnCount())
    {//如果表头列数变化,重新初始化
        QStringList strList;
        for (int i=0;i<theModel->columnCount();i++)//获取现有的表头标题
            strList.append(theModel->headerData(i,Qt::Horizontal,Qt::DisplayRole).toString());
        dlgSetHeaders->setHeaderList(strList);//用于对话框初始化显示
    }

    int ret=dlgSetHeaders->exec();// 以模态方式显示对话框
    if (ret==QDialog::Accepted) //OK键被按下
    {
        QStringList strList=dlgSetHeaders->headerList();//获取对话框上修改后的StringList
        theModel->setHorizontalHeaderLabels(strList);// 设置模型的表头标题
    }

}

void MainWindow::on_actTab_Locate_triggered()
{
    //创建 StayOnTop的对话框,对话框关闭时自动删除
     //通过控制actTab_Locate的enable属性避免重复点击

        ui->actTab_Locate->setEnabled(false);

        dlgLocate = new QWDialogLocate(this); //创建对话框,传递指针
        dlgLocate->setAttribute(Qt::WA_DeleteOnClose); //对话框关闭时自动删除对话框对象,用于不需要读取返回值的对话框
        Qt::WindowFlags    flags=dlgLocate->windowFlags(); //获取已有flags
    //对话框设置为固定大小和StayOnTop
    //    dlgLocate->setWindowFlags(flags |Qt::MSWindowsFixedSizeDialogHint |Qt::WindowStaysOnTopHint); //设置对话框固定大小,StayOnTop
        dlgLocate->setWindowFlags(flags | Qt::WindowStaysOnTopHint); //设置对话框固定大小,StayOnTop
    //对话框初始化设置
        dlgLocate->setSpinRange(theModel->rowCount(),theModel->columnCount());
        QModelIndex curIndex=theSelection->currentIndex();
        if (curIndex.isValid())
           dlgLocate->setSpinValue(curIndex.row(),curIndex.column());

        dlgLocate->show(); //非模态显示对话框
}

void MainWindow::on_tableView_clicked(const QModelIndex &index)
{
    //单击单元格时,将单元格的行号、列号设置到对话框上
    if (dlgLocate!=NULL) //对话框存在
         dlgLocate->setSpinValue(index.row(),index.column());
}

代码部分在注释里有,这里不在详细介绍。对应的部分请看5.9书籍

发布了26 篇原创文章 · 获赞 7 · 访问量 4310

猜你喜欢

转载自blog.csdn.net/weixin_42126427/article/details/104161439