mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class QAction;
class QMenu;
class QToolBar;
class QLabel;
class FindDialog;
class Spreadsheet;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
void closeEvent(QCloseEvent *event);
private slots:
void newFile();
bool okToContinue();
void open();
bool save();
bool saveAs();
bool saveFile(const QString &fileName);
bool loadFile(const QString &fileName);
void setCurrentFile(const QString &fileName);
QString strippedName(const QString &fullFileName);
void find();
void goToCell();
void sort();
void about();
void openRecentFile();
void updateStatusBar();
void spreadsheetModified();
private:
Ui::MainWindow *ui;
FindDialog *findDialog;
Spreadsheet *spreadsheet;
QString currentFileName;
void createActions();
void createMenus();
void createFileActions();
void createEditActions();
void createToolsActions();
void createOptionsActions();
void createHelpActions();
void createToolBars();
void createStatusBar();
void createContextMenu();
void readSettings();
void writeSettings();
void updateRecentFileAction();
QStringList recentFiles;
QString curFile;
/*最近浏览文件*/
enum {MaxRecentFiles=5};
QAction *recentFileActions[MaxRecentFiles];
QAction *separatorAction;
/*菜单*/
QMenu *fileMenu;
QMenu *editMenu;
QMenu *toolsMenu;
QMenu *optionsMenu;
QMenu *helpMenu;
/*工具栏*/
QToolBar *fileToolBar;
QToolBar *editToolBar;
/*状态栏标签*/
QLabel *locationLabel;
QLabel *formulaLabel;
/*File动作*/
QAction *newAction;
QAction *openAction;
QAction *saveAction;
QAction *saveAsAction;
QAction *exitAction;
/*Edit动作*/
QAction *cutAction;
QAction *copyAction;
QAction *pasteAction;
QAction *deleteAction;
QMenu *selectSubMenu;
QAction *selectRowAction;
QAction *selectColumnAction;
QAction *selectAllAction;
QAction *findAction;
QAction *goToCellAction;
/*Tools动作*/
QAction *recalculateAction;
QAction *sortAction;
/*Options动作*/
QAction *showGridAction;
QAction *autoRecalcAction;
/*Help动作*/
QAction *aboutAction;
QAction *aboutQtAction;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include <QtWidgets>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "spreadsheet.h"
#include "finddialog.h"
#include "gotocelldialog.h"
#include "sortdialog.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
spreadsheet =new Spreadsheet(this);
setCentralWidget(spreadsheet);
createActions();
createMenus();
createToolBars();
createStatusBar();
readSettings();
findDialog= nullptr;
setWindowIcon(QIcon(":/image/clear.png"));
setCurrentFile("");
}
void MainWindow::createMenus()
{
/*file menu*/
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(newAction);
fileMenu->addAction(openAction);
fileMenu->addAction(saveAction);
fileMenu->addAction(saveAsAction);
separatorAction=fileMenu->addSeparator();
for (int i=0;i<MaxRecentFiles;++i)
fileMenu->addAction(recentFileActions[i]);
fileMenu->addSeparator();
fileMenu->addAction(exitAction);
/*edit menu*/
editMenu = menuBar()->addMenu(tr("&Edit"));
editMenu->addAction(cutAction);
editMenu->addAction(copyAction);
editMenu->addAction(pasteAction);
editMenu->addAction(deleteAction);
selectSubMenu = editMenu->addMenu(tr("&Select"));
selectSubMenu->addAction(selectRowAction);
selectSubMenu->addAction(selectColumnAction);
selectSubMenu->addAction(selectAllAction);
editMenu->addSeparator();
editMenu->addAction(findAction);
editMenu->addAction(goToCellAction);
/*tools menu*/
toolsMenu = menuBar()->addMenu(tr("&Tools"));
toolsMenu->addAction(recalculateAction);
toolsMenu->addAction(sortAction);
menuBar()->addSeparator();
/*option menu*/
optionsMenu = menuBar()->addMenu(tr("&Option"));
optionsMenu->addAction(showGridAction);
optionsMenu->addAction(autoRecalcAction);
/*间隔器*/
menuBar()->addSeparator();
/*help menu*/
helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(aboutAction);
helpMenu->addAction(aboutQtAction);
}
void MainWindow::createActions()
{
createFileActions();
createEditActions();
createToolsActions();
createOptionsActions();
createHelpActions();
}
void MainWindow::createContextMenu()
{
spreadsheet->addAction(cutAction);
spreadsheet->addAction(copyAction);
spreadsheet->addAction(pasteAction);
spreadsheet->setContextMenuPolicy(Qt::ActionsContextMenu);
}
/*工具栏*/
void MainWindow::createToolBars()
{
fileToolBar = addToolBar(tr("&File"));
fileToolBar->addAction(newAction);
fileToolBar->addAction(openAction);
fileToolBar->addAction(saveAction);
editToolBar = addToolBar(tr("&Edit"));
editToolBar->addAction(cutAction);
editToolBar->addAction(copyAction);
editToolBar->addAction(pasteAction);
editToolBar->addSeparator();
editToolBar->addAction(findAction);
editToolBar->addAction(goToCellAction);
}
/*状态栏*/
void MainWindow::createStatusBar()
{
/* W999 作用:1.显示的内容。2.决定locationLabel的尺寸大小*/
locationLabel = new QLabel(" W999 ");
/*对齐方式:居中对齐*/
locationLabel->setAlignment(Qt::AlignHCenter);
/*最小大小为窗口部件的理想大小*/
locationLabel->setMinimumSize(locationLabel->sizeHint());
formulaLabel = new QLabel;
/*缩进,文本与左侧边的偏移量*/
formulaLabel->setIndent(3);
/*单元格定位指示器,伸展因子默认为0*/
statusBar()->addWidget(locationLabel);
/*单元格公式指示器,伸展因子为1*/
statusBar()->addWidget(formulaLabel, 1);
connect(spreadsheet,SIGNAL(currentCellChanged(int,int,int,int)),this,SLOT(updateStatusBar()));
connect(spreadsheet,SIGNAL(modified()),this,SLOT(spreadsheetModified()));
updateStatusBar();
}
void MainWindow::updateStatusBar()
{
locationLabel->setText(spreadsheet->currentLocation());
formulaLabel->setText(spreadsheet->currentFormula());
}
void MainWindow::spreadsheetModified()
{
setWindowModified(true);
updateStatusBar();
}
void MainWindow::createFileActions()
{
/*newAction*/
newAction=new QAction(tr("&New"),this);
newAction->setIcon(QIcon(":/image/load.png"));
newAction->setShortcut(QKeySequence::New);
newAction->setStatusTip(tr("Create a new spreadsheet file"));
connect(newAction,SIGNAL(triggered()),this,SLOT(newFile()));
/*openAction*/
openAction = new QAction(tr("&Open"), this);
openAction->setIcon(QIcon(":/image/massload.png"));
openAction->setShortcut(QKeySequence::Open);
openAction->setStatusTip(tr("Opne an existing spreadsheet file"));
connect(openAction,SIGNAL(triggered()),this,SLOT(open()));
/*saveAction*/
saveAction = new QAction(tr("&Save"), this);
saveAction->setIcon(QIcon(":/image/save.png"));
saveAction->setShortcut(QKeySequence::Save);
saveAction->setStatusTip(tr("Save the spreadsheet to disk"));
connect(saveAction,SIGNAL(triggered()),this,SLOT(save()));
/*saveAsAction*/
saveAsAction = new QAction(tr("Save &As..."), this);
saveAsAction->setIcon(QIcon(":/image/save-as.png"));
saveAsAction->setShortcut(QKeySequence::SaveAs);
saveAsAction->setStatusTip(tr("Save the spreadsheet under a new name"));
connect(saveAsAction,SIGNAL(triggered()),this,SLOT(saveAs()));
/*openRecentFile*/
for (int i =0;i<MaxRecentFiles;++i)
{
recentFileActions[i]=new QAction(this);
recentFileActions[i]->setVisible(false);
connect(recentFileActions[i],SIGNAL(triggered()),this,SLOT(openRecentFile()));
}
/*exitAction */
exitAction = new QAction(tr("&Exit"), this);
exitAction->setShortcut(tr("Ctrl+Q"));
exitAction->setStatusTip(tr("Exit the application"));
connect(exitAction,SIGNAL(triggered()),this,SLOT(close()));
}
/*edit动作*/
void MainWindow::createEditActions()
{
/*cutAction*/
cutAction = new QAction(tr("Cu&t"), this);
cutAction->setIcon(QIcon(":/image/cut.png"));
cutAction->setShortcut(QKeySequence::Cut);
cutAction->setStatusTip(tr("Cut the Current selection's "
"contents to the clipboard"));
/*copyAction*/
copyAction = new QAction(tr("&Copy"), this);
copyAction->setIcon(QIcon(":/image/copy.png"));
copyAction->setShortcut(QKeySequence::Copy);
copyAction->setStatusTip(tr("Copy the current selection's "
"contents to the clipboard"));
/*pasteAction*/
pasteAction = new QAction(tr("&Paste"), this);
pasteAction->setIcon(QIcon(":/image/paste.png"));
pasteAction->setShortcut(QKeySequence::Paste);
pasteAction->setStatusTip(tr("Paste the clipboard's "
"contents into the current selection"));
/*deleteAction*/
deleteAction = new QAction(tr("&Delete"), this);
deleteAction->setIcon(QIcon(":/image/delete.png"));
deleteAction->setShortcut(QKeySequence::Delete);
deleteAction->setStatusTip(tr("Delete the current selection's " "contents"));
selectRowAction = new QAction(tr("&Row"), this);
selectRowAction->setStatusTip(tr("Select all the cells in "
"the current row"));
selectColumnAction = new QAction(tr("&Column"), this);
selectColumnAction->setStatusTip(tr("Select all the cells in "
"the current column"));
selectAllAction = new QAction(tr("&All"), this);
selectAllAction->setShortcut(QKeySequence::SelectAll);
selectAllAction->setStatusTip(tr("Select all the cells in "
"the spreadsheet"));
connect(selectAllAction,SIGNAL(triggered()),spreadsheet,SLOT(selectAll()));
/*findAction*/
findAction = new QAction(tr("&Find..."), this);
findAction->setIcon(QIcon(":/image/enlarge.png"));
findAction->setShortcut(QKeySequence::Find);
findAction->setStatusTip(tr("Find a matching cell"));
connect(findAction,SIGNAL(triggered()),this,SLOT(find()));
/*goToCellAction*/
goToCellAction = new QAction(tr("&Go to Cell..."), this);
goToCellAction->setIcon(QIcon(":/image/reduce"));
goToCellAction->setShortcut(tr("Ctrl+G"));
}
/*tools动作*/
void MainWindow::createToolsActions()
{
recalculateAction = new QAction(tr("&Recalculate"), this);
recalculateAction->setShortcut(tr("F9"));
recalculateAction->setStatusTip(tr("Recalculate all the "
"spreadsheet's formulas"));
sortAction = new QAction(tr("&Sort..."), this);
sortAction->setStatusTip(tr("Sort the selected cells or all "
"the cells"));
}
/*options动作*/
void MainWindow::createOptionsActions()
{
showGridAction = new QAction(tr("&Show Grid"), this);
showGridAction->setCheckable(true); /*使动作可被选*/
showGridAction->setStatusTip(tr("Show or hide the "
"spreadsheet's grid"));
connect(showGridAction,SIGNAL(toggled(bool)),spreadsheet,SLOT(setShowGrid(bool)));
autoRecalcAction = new QAction(tr("Auto-Recalculate"), this);
autoRecalcAction->setCheckable(true); /*使动作可被选*/
autoRecalcAction->setStatusTip(tr("Switch auto-"
"recalculate on or off"));
}
/*help动作*/
void MainWindow::createHelpActions()
{
aboutAction = new QAction(tr("&About"), this);
aboutAction->setStatusTip(tr("Show the application's "
"About box"));
aboutQtAction = new QAction(tr("About &Qt"), this);
aboutQtAction->setStatusTip(tr("Show the Qt library's "
"About box"));
connect(aboutAction,SIGNAL(triggered()),this,SLOT(about()));
connect(aboutQtAction,SIGNAL(triggered()),qApp,SLOT(aboutQt()));
}
void MainWindow::setCurrentFile(const QString &fileName)
{
currentFileName = fileName;
/*true:保存过和未保存有区别;false:无区别*/
setWindowModified(true);
QString shownName = tr("Untitled");
if (!currentFileName.isEmpty())
{
shownName = strippedName(currentFileName); /*名字去掉路径*/
}
/*[*]:当WindowModified属性为true时,保存过的文件才没有星号*/
setWindowTitle(tr("%1[*] - %2").arg(shownName)
.arg("Spreadsheet"));
}
/*去掉路径,只保留文件名*/
QString MainWindow::strippedName(const QString &fullFileName)
{
return QFileInfo(fullFileName).fileName();
}
/************************具体功能实现*******************************/
void MainWindow::newFile()
{
MainWindow* mainWin=new MainWindow;
mainWin->show();
// if (okToContinue()) {
// spreadsheet->clear();
// setCurrentFile("");
// }
}
bool MainWindow::okToContinue()
{
if (isWindowModified()){
int r=QMessageBox::warning(this,tr("Spreadsheet"),tr("The document has been modified.\n""Do you want to save your changes?"),QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel);
if (r==QMessageBox::Yes){
return save();
}else if(r==QMessageBox::Cancel){
return false;
}
}
return true;
}
void MainWindow::open()
{
if(okToContinue()){
QString fileName=QFileDialog::getOpenFileName(this,tr("Open Spreadsheet"),".",tr("Spreadsheet files(*.sp)\n""Comma-separated values files(*.csv)\n"));
if (!fileName.isEmpty())
loadFile(fileName);
}
}
void MainWindow::openRecentFile()
{
if(okToContinue()){
QAction *action=qobject_cast<QAction *>(sender());
if (action)
loadFile(action->data().toString());
}
}
bool MainWindow::loadFile(const QString &fileName)
{
if (!spreadsheet->readFile(fileName))
{
statusBar()->showMessage(tr("Loading canceled"), 2000);
} return false;
setCurrentFile(fileName);
statusBar()->showMessage( tr("File loaded"), 2000);
return true;
}
bool MainWindow::saveAs()
{
QString fileName = QFileDialog::getSaveFileName( this, tr("Save Spreadsheet"), "." , tr("Spreadsheet files (*.sp)") );
if( fileName.isEmpty() ) return false;
return saveFile(fileName);
}
bool MainWindow::save()
{
if (curFile.isEmpty()){
return saveAs();
}else{
return saveFile(curFile);
}
}
bool MainWindow::saveFile(const QString &fileName)
{
if (!spreadsheet->writeFile(fileName)){
statusBar()->showMessage(tr("Saving canceled"), 2000);} return false;
setCurrentFile(fileName);
statusBar()->showMessage( tr("File loaded"), 2000);
return true;
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if (okToContinue()){
writeSettings();
event->accept();
}else {
event->ignore();
}
}
//void MainWindow::setCurrentFile(const QString &fileName)
//{
// curFile=fileName;
// setWindowModified(false);
// QString showName=tr("Untitled");
// if (!curFile.isEmpty()){
// showName=strippedName(curFile);
// recentFiles.removeAll(curFile);
// recentFiles.prepend(curFile);
// updateRecentFileAction();
// }
// setWindowTitle(tr("%1[*]-%2").arg(showName).arg(tr("Spreadsheet")));
//}
//QString MainWindow::strippedName(const QString &fullFileName)
//{
// return QFileInfo(fullFileName).fileName();
//}
void MainWindow::updateRecentFileAction()
{
// QSettings settings("Trolltech", "Recent Files Example");
// QStringList files = settings.value("recentFileList").toStringList();
// int numRecentFiles = qMin(files.size(), int(MaxRecentFiles));
// for (int i = 0; i < numRecentFiles; ++i) {
// QString text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i]));
// recentFileActions[i]->setText(text);
// recentFileActions[i]->setData(files[i]);
// recentFileActions[i]->setVisible(true);
// }
// for (int j = numRecentFiles; j < MaxRecentFiles; ++j)
// recentFileActions[j]->setVisible(false);
// separatorAction->setVisible(numRecentFiles > 0);
QMutableStringListIterator i(recentFiles);
while (i.hasNext()) {
if (!QFile::exists(i.next()))
i.remove();
}
for (int j = 0; j < MaxRecentFiles; ++j) {
if (j < recentFiles.count()) {
QString text = tr("&%1 %2")
.arg(j + 1)
.arg(strippedName(recentFiles[j]));
recentFileActions[j]->setText(text);
recentFileActions[j]->setData(recentFiles[j]);
recentFileActions[j]->setVisible(true);
} else {
recentFileActions[j]->setVisible(false);
}
}
separatorAction->setVisible(!recentFiles.isEmpty());
}
void MainWindow::find()
{
if (!findDialog) {
findDialog = new FindDialog(this);
connect(findDialog, SIGNAL(findNext(const QString &,
Qt::CaseSensitivity)),
spreadsheet, SLOT(findNext(const QString &,
Qt::CaseSensitivity)));
connect(findDialog, SIGNAL(findPrevious(const QString &,
Qt::CaseSensitivity)),
spreadsheet, SLOT(findPrevious(const QString &,
Qt::CaseSensitivity)));
}
findDialog->show();
findDialog->raise();
findDialog->activateWindow();
}
void MainWindow::goToCell()
{
GoToCellDialog dialog;
//GoToCellDialog dialog(this);
if (dialog.exec()) {
QString str = dialog.lineEdit->text().toUpper();
spreadsheet->setCurrentCell(str.mid(1).toInt() - 1,
str[0].unicode() - 'A');
}
}
void MainWindow::sort()
{
// SortDialog dialog;
// //SortDialog dialog(this);
// QTableWidgetSelectionRange range = spreadsheet->selectedRange();
// dialog.setColumnRange('A' + range.leftColumn(),
// 'A' + range.rightColumn());
// if (dialog.exec()) {
// SpreadsheetCompare compare;
// compare.keys[0] =
// dialog.primaryColumnCombo->currentIndex();
// compare.keys[1] =
// dialog.secondaryColumnCombo->currentIndex() - 1;
// compare.keys[2] =
// dialog.tertiaryColumnCombo->currentIndex() - 1;
// compare.ascending[0] =
// (dialog.primaryOrderCombo->currentIndex() == 0);
// compare.ascending[1] =
// (dialog.secondaryOrderCombo->currentIndex() == 0);
// compare.ascending[2] =
// (dialog.tertiaryOrderCombo->currentIndex() == 0);
// spreadsheet->sort(compare);
// }
}
void MainWindow::about()
{
QMessageBox::about(this, tr("About Spreadsheet"),
tr("<h2>Spreadsheet 1.1</h2>"
"<p>Copyright © 2008 Software Inc."
"<p>Spreadsheet is a small application that "
"demonstrates QAction, QMainWindow, QMenuBar, "
"QStatusBar, QTableWidget, QToolBar, and many other "
"Qt classes."));
}
void MainWindow::readSettings()
{
QSettings settings("Software Inc.", "Spreadsheet");restoreGeometry(settings.value("geometry").toByteArray());
recentFiles = settings.value("recentFiles").toStringList();
updateRecentFileAction();
bool showGrid = settings.value("showGrid", true).toBool();
showGridAction->setChecked(showGrid);
bool autoRecalc = settings.value("autoRecalc", true).toBool();
autoRecalcAction->setChecked(autoRecalc);
}
void MainWindow::writeSettings()
{
QSettings settings("Software Inc.", "Spreadsheet");
settings.setValue("geometry", saveGeometry());
settings.setValue("recentFiles", recentFiles);
settings.setValue("showGrid", showGridAction->isChecked());
settings.setValue("autoRecalc", autoRecalcAction->isChecked());
}
MainWindow::~MainWindow()
{
delete ui;
}
主界面
多窗口
编辑
关于
无网格