今天看一下第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 ¤t, 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 ¤t, 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书籍