子类化QMainWindow:
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class QAction;
class QLabel;
class FindDialog;
class Spreadsheet;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
protected:
//closeEvent是QWidget类中的一个虚函数 当用户关闭窗口时,函数会自动被调用
//就可以想用户询问一些问题 并把一些偏好设置保存到磁盘中
void closeEvent(QCloseEvent *event);
//槽返回值一般会被忽略 但是如果是一个普通函数的话 其返回值和普通的
//c++函数作用是一致的
private slots:
void newFile();
void open();
bool save();
bool saveAs();
void find();
void goToCell();
void sort();
void about();
//当从file总点击最近的文件时 就要调用此函数!
void openRecentFile();
void updateStatusBar();
void spreadsheetModified();
private:
void createActions();
void createMenus();
void createContextMenu();
void createToolBars();
void createStatusBar();
void readSettings();
void writeSettings();
bool okToContinue();
bool loadFile(const QString &fileName);
bool saveFile(const QString &fileName);
void setCurrentFile(const QString &fileName);
void updateRecentFileActions();
QString strippedName(const QString &fullFileName);
Spreadsheet *spreadsheet;
FindDialog *findDialog;
QLabel *locationLabel;
QLabel *formulaLabel;
QStringList recentFiles;
QString curFile;
enum { MaxRecentFiles = 5 };//利用枚举定义常量
QAction *recentFileActions[MaxRecentFiles];
QAction *separatorAction; //建立分隔符
QMenu *fileMenu;
QMenu *editMenu;
QMenu *selectSubMenu;
QMenu *toolsMenu;
QMenu *optionsMenu;
QMenu *helpMenu;
QToolBar *fileToolBar;
QToolBar *editToolBar;
QAction *newAction;
QAction *openAction;
QAction *saveAction;
QAction *saveAsAction;
QAction *exitAction;
QAction *cutAction;
QAction *copyAction;
QAction *pasteAction;
QAction *deleteAction;
QAction *selectRowAction;
QAction *selectColumnAction;
QAction *selectAllAction;
QAction *findAction;
QAction *goToCellAction;
QAction *recalculateAction;
QAction *sortAction;
QAction *showGridAction;
QAction *autoRecalcAction;
QAction *aboutAction;
QAction *aboutQtAction;
};
#endif
QT资源文件的学习:http://www.devbean.net/2012/08/qt-study-road-2-resource-files/
菜单的创建
newAction = new QAction(tr("&New"), this);
newAction->setIcon(QIcon(":/images/new.png"));
newAction->setShortcut(QKeySequence::New);
newAction->setStatusTip(tr("Create a new spreadsheet file"));
connect(newAction, SIGNAL(triggered()), this, SLOT(newFile()));
当没有指定的用于终止应用程序的标准化键序列 需要自定义
//并没有标准的用于终止应用程序的标准化键序列 所以需要自定义
exitAction->setShortcut(tr("Ctrl+Q"));
当菜单是复选框的效果的时候: (注:如果有复选框肯定有两种状态 选择toggled(bool) 如果不是有两种状态选择triggered()来触发)
//复选框菜单
showGridAction = new QAction(tr("&Show Grid"), this);
showGridAction->setCheckable(true);
showGridAction->setChecked(spreadsheet->showGrid());
showGridAction->setStatusTip(tr("Show or hide the spreadsheet's ""grid"));
//toggle的意思是开关 所以checkable用此函数来激活
//triggered()是触发普通按钮的
connect(showGridAction, SIGNAL(toggled(bool)),
spreadsheet, SLOT(setShowGrid(bool)));
如果复选框想要有互斥的操作 使用QActiongroup操作:
QActionGroup的应用:http://hi.baidu.com/yioopayczwgnsye/item/78f2ae95657883dc1f4271e3
//设置所能包含的最大字符字数,
locationLabel = new QLabel(" Q999 ");
//居中对齐
/*Qt::AlignLeft 左对齐
Qt::AlignRight 右对齐
Qt::AlignHCenter 居中
Qt::AlignTop 顶部对齐
Qt::AlignBottom 底部对齐*/
//定位指示器
locationLabel->setAlignment(Qt::AlignHCenter);
//设置Label的最小大小
locationLabel->setMinimumSize(locationLabel->sizeHint());
//单位格公式指示器
formulaLabel = new QLabel;
//缩进长度
formulaLabel->setIndent(20);
statusBar()->addWidget(locationLabel);
//第二个参数指定伸展因子
statusBar()->addWidget(formulaLabel,1);
创建菜单: menuBar()是QMainwindow创建的时候就有的
//menuBar()返回一个QMenuBar()的指针
//QMenuBar *menuBar = new QMenuBar(0);
//mainwindwo已经自带menubar toolbar() status
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(newAction);
fileMenu->addAction(openAction);
fileMenu->addAction(saveAction);
fileMenu->addAction(saveAsAction);创建子菜单:
//在menu的下面再创建子菜单
selectSubMenu = editMenu->addMenu(tr("&Select"));
selectSubMenu->addAction(selectRowAction);
selectSubMenu->addAction(selectColumnAction);
selectSubMenu->addAction(selectAllAction);
如果要让一个窗口有右键菜单:
//任何窗口都可以添加一个与之相连的QActions列表
spreadsheet->addAction(cutAction);
spreadsheet->addAction(copyAction);
spreadsheet->addAction(pasteAction);
//将窗口的上下文菜单策略设置为一个显示动作的上下文菜单
spreadsheet->setContextMenuPolicy(Qt::ActionsContextMenu);
由于QMainwindow不只有一个toolbar 所以没有Toolbar()参数
//增加一个toolbar toolbar是不可见的 但是有分隔符
//toolbai并不是系统自带的!!
fileToolBar = addToolBar(tr("&File"));
fileToolBar->addAction(newAction);
fileToolBar->addAction(openAction);
fileToolBar->addAction(saveAction);
实现file菜单
如果窗口改变了 需要有一个提示
if (isWindowModified()) {
//QMessageBox提供了许多标准按钮,按ESC退出
//QMessageBox还提供了information、question()、critical()函数,
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;
}
}
if (okToContinue()) {
// //第四个参数指定文件过滤器:描述文本+通配符构成
///也可以使用多个文件过滤器
///tr("...\n""...\n")
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Spreadsheet"), ".",
tr("Spreadsheet files (*.sp)"));
if (!fileName.isEmpty())
loadFile(fileName);
}
通过写注册表来进行存储设置:
void MainWindow::readSettings()
{
QSettings settings("Software Inc.", "Spreadsheet");
restoreGeometry(settings.value("geometry").toByteArray());
recentFiles = settings.value("recentFiles").toStringList();
updateRecentFileActions();
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.cpp
#include <QtGui>
#include "finddialog.h"
#include "gotocelldialog.h"
#include "mainwindow.h"
#include "sortdialog.h"
#include "spreadsheet.h"
MainWindow::MainWindow()
{
spreadsheet = new Spreadsheet;
//创建中心窗口
setCentralWidget(spreadsheet);
createActions();
createMenus();
createContextMenu();
createToolBars();
createStatusBar();
readSettings();
//将finddialog设置为空指针
findDialog = 0;
//设置图标
//使用qt的资源机制
setWindowIcon(QIcon(":/images/icon.png"));
setCurrentFile("");
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if (okToContinue()) {
writeSettings();
event->accept();
} else {
event->ignore();
}
}
void MainWindow::newFile()
{
if (okToContinue()) {
spreadsheet->clear();
setCurrentFile("");
}
}
void MainWindow::open()
{
if (okToContinue()) {
// //第四个参数指定文件过滤器:描述文本+通配符构成
///也可以使用多个文件过滤器
///tr("...\n""...\n")
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Spreadsheet"), ".",
tr("Spreadsheet files (*.sp)"));
if (!fileName.isEmpty())
loadFile(fileName);
}
}
bool MainWindow::save()
{
if (curFile.isEmpty()) {
return saveAs();
} else {
return saveFile(curFile);
}
}
bool MainWindow::saveAs()
{
QString fileName = QFileDialog::getSaveFileName(this,
tr("Save Spreadsheet"), ".",
tr("Spreadsheet files (*.sp)"));
if (fileName.isEmpty())
return false;
return saveFile(fileName);
}
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();
//让窗口称为顶层窗口 raise()
//让窗口到下面 lower()
findDialog->raise();
//当已经可见时, show没有效果,必须使用activeWindow()让窗口重新获得焦点
findDialog->activateWindow();
}
//希望用户可以弹出、使用和关闭它 但是不允许切换
//所以这是一个模态状态
void MainWindow::goToCell()
{
//这个对象希望是临时的 使用完毕后直接关闭
//所以在堆栈直接建立了一个作为变量的窗口部件
GoToCellDialog dialog(this);
//使用show就是非模态对话框
//使用exec就是使用模态对话框 exec是执行
//dialog.exec() 其实是当gotocell点击ok的时候
if (dialog.exec()) {
//对字符str的切割
QString str = dialog.lineEdit->text().toUpper();
//QString::unicode Returns a '\0'-terminated Unicode representation of the string. The result remains valid until the string is modified.
//QString内部采用的是 Unicode,它可以同时存放GBK中的字符"我是汉字",BIG5中的字符"扂岆犖趼" 以及Latin-1中的字符"ÎÒÊǺº×Ö"。
/*mid 本身有中间的意思
*此成员函数从此QString对象中提取一个长度为nCount个字符的子串,
*从nFirst(从零开始的索引)指定的位置开始。此函数返回一个对所提取的字符串的拷贝。
*Mid类似于Basic MID$函数(除了索引是从零开始的)。
*/
//用str[0].toascii叶师可以的
spreadsheet->setCurrentCell(str.mid(1).toInt() - 1,
str[0].unicode() - 'A');
}
}
void MainWindow::sort()
{
SortDialog dialog(this);
QTableWidgetSelectionRange range = spreadsheet->selectedRange();
dialog.setColumnRange('A' + range.leftColumn(),
'A' + range.rightColumn());
if (dialog.exec()) {
//compare对象存储了主键、第二键、第三键以及他们的排序顺序
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::openRecentFile()
{
if (okToContinue()) {
//dynamic_cast动态识别
//qobject_cast可以跨越动态库 这是它与dynamic_cast的区别
//sender
QAction *action = dynamic_cast<QAction *>(sender());
if (action)
loadFile(action->data().toString());
}
}
//当移动窗口的时候
void MainWindow::updateStatusBar()
{
locationLabel->setText(spreadsheet->currentLocation());
formulaLabel->setText(spreadsheet->currentFormula());
}
void MainWindow::spreadsheetModified()
{
//窗口标题可以改变 改变的话就在文件名后面+* 不改变就不加*
setWindowModified(true);
updateStatusBar();
}
void MainWindow::createActions()
{
newAction = new QAction(tr("&New"), this);
newAction->setIcon(QIcon(":/images/new.png"));
newAction->setShortcut(QKeySequence::New);
newAction->setStatusTip(tr("Create a new spreadsheet file"));
connect(newAction, SIGNAL(triggered()), this, SLOT(newFile()));
openAction = new QAction(tr("&Open..."), this);
openAction->setIcon(QIcon(":/images/open.png"));
openAction->setShortcut(QKeySequence::Open);
openAction->setStatusTip(tr("Open an existing spreadsheet file"));
connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
saveAction = new QAction(tr("&Save"), this);
saveAction->setIcon(QIcon(":/images/save.png"));
saveAction->setShortcut(QKeySequence::Save);
saveAction->setStatusTip(tr("Save the spreadsheet to disk"));
connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));
saveAsAction = new QAction(tr("Save &As..."), this);
saveAsAction->setStatusTip(tr("Save the spreadsheet under a new "
"name"));
connect(saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs()));
//必须为每个action指定一个槽,但是这个槽为了获取是哪个动作触发的
//就必须使用QObject::sender()来调查是哪个对象发起的
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 = new QAction(tr("E&xit"), this);
//并没有标准的用于终止应用程序的标准化键序列 所以需要自定义
exitAction->setShortcut(tr("Ctrl+Q"));
exitAction->setStatusTip(tr("Exit the application"));
connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
cutAction = new QAction(tr("Cu&t"), this);
cutAction->setIcon(QIcon(":/images/cut.png"));
cutAction->setShortcut(QKeySequence::Cut);
cutAction->setStatusTip(tr("Cut the current selection's contents "
"to the clipboard"));
connect(cutAction, SIGNAL(triggered()), spreadsheet, SLOT(cut()));
copyAction = new QAction(tr("&Copy"), this);
copyAction->setIcon(QIcon(":/images/copy.png"));
copyAction->setShortcut(QKeySequence::Copy);
copyAction->setStatusTip(tr("Copy the current selection's contents "
"to the clipboard"));
connect(copyAction, SIGNAL(triggered()), spreadsheet, SLOT(copy()));
pasteAction = new QAction(tr("&Paste"), this);
pasteAction->setIcon(QIcon(":/images/paste.png"));
pasteAction->setShortcut(QKeySequence::Paste);
pasteAction->setStatusTip(tr("Paste the clipboard's contents into "
"the current selection"));
connect(pasteAction, SIGNAL(triggered()),
spreadsheet, SLOT(paste()));
deleteAction = new QAction(tr("&Delete"), this);
deleteAction->setShortcut(QKeySequence::Delete);
deleteAction->setStatusTip(tr("Delete the current selection's "
"contents"));
connect(deleteAction, SIGNAL(triggered()),
spreadsheet, SLOT(del()));
selectRowAction = new QAction(tr("&Row"), this);
selectRowAction->setStatusTip(tr("Select all the cells in the "
"current row"));
connect(selectRowAction, SIGNAL(triggered()),
spreadsheet, SLOT(selectCurrentRow()));
selectColumnAction = new QAction(tr("&Column"), this);
selectColumnAction->setStatusTip(tr("Select all the cells in the "
"current column"));
connect(selectColumnAction, SIGNAL(triggered()),
spreadsheet, SLOT(selectCurrentColumn()));
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 = new QAction(tr("&Find..."), this);
findAction->setIcon(QIcon(":/images/find.png"));
findAction->setShortcut(QKeySequence::Find);
findAction->setStatusTip(tr("Find a matching cell"));
connect(findAction, SIGNAL(triggered()), this, SLOT(find()));
goToCellAction = new QAction(tr("&Go to Cell..."), this);
goToCellAction->setIcon(QIcon(":/images/gotocell.png"));
goToCellAction->setShortcut(tr("Ctrl+G"));
goToCellAction->setStatusTip(tr("Go to the specified cell"));
connect(goToCellAction, SIGNAL(triggered()),
this, SLOT(goToCell()));
recalculateAction = new QAction(tr("&Recalculate"), this);
recalculateAction->setShortcut(tr("F9"));
recalculateAction->setStatusTip(tr("Recalculate all the "
"spreadsheet's formulas"));
connect(recalculateAction, SIGNAL(triggered()),
spreadsheet, SLOT(recalculate()));
sortAction = new QAction(tr("&Sort..."), this);
sortAction->setStatusTip(tr("Sort the selected cells or all the "
"cells"));
connect(sortAction, SIGNAL(triggered()), this, SLOT(sort()));
//复选框菜单
showGridAction = new QAction(tr("&Show Grid"), this);
showGridAction->setCheckable(true);
showGridAction->setChecked(spreadsheet->showGrid());
showGridAction->setStatusTip(tr("Show or hide the spreadsheet's ""grid"));
//toggle的意思是开关 所以checkable用此函数来激活
//triggered()是触发普通按钮的
connect(showGridAction, SIGNAL(toggled(bool)),
spreadsheet, SLOT(setShowGrid(bool)));
#if QT_VERSION < 0x040102
// workaround for a QTableWidget bug in Qt 4.1.1
connect(showGridAction, SIGNAL(toggled(bool)),
spreadsheet->viewport(), SLOT(update()));
#endif
autoRecalcAction = new QAction(tr("&Auto-Recalculate"), this);
autoRecalcAction->setCheckable(true);
autoRecalcAction->setChecked(spreadsheet->autoRecalculate());
autoRecalcAction->setStatusTip(tr("Switch auto-recalculation on or "
"off"));
connect(autoRecalcAction, SIGNAL(toggled(bool)),
spreadsheet, SLOT(setAutoRecalculate(bool)));
aboutAction = new QAction(tr("&About"), this);
aboutAction->setStatusTip(tr("Show the application's About box"));
connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
aboutQtAction = new QAction(tr("About &Qt"), this);
aboutQtAction->setStatusTip(tr("Show the Qt library's About box"));
connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
}
//创建一个包含这些动作的菜单系统
void MainWindow::createMenus()
{
//menuBar()返回一个QMenuBar()的指针
//QMenuBar *menuBar = new QMenuBar(0);
//mainwindwo已经自带menubar toolbar() status
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菜单下面要添加一个分隔符
editMenu = menuBar()->addMenu(tr("&Edit"));
editMenu->addAction(cutAction);
editMenu->addAction(copyAction);
editMenu->addAction(pasteAction);
editMenu->addAction(deleteAction);
//在menu的下面再创建子菜单
selectSubMenu = editMenu->addMenu(tr("&Select"));
selectSubMenu->addAction(selectRowAction);
selectSubMenu->addAction(selectColumnAction);
selectSubMenu->addAction(selectAllAction);
editMenu->addSeparator();
editMenu->addAction(findAction);
editMenu->addAction(goToCellAction);
toolsMenu = menuBar()->addMenu(tr("&Tools"));
toolsMenu->addAction(recalculateAction);
toolsMenu->addAction(sortAction);
optionsMenu = menuBar()->addMenu(tr("&Options"));
optionsMenu->addAction(showGridAction);
optionsMenu->addAction(autoRecalcAction);
menuBar()->addSeparator();
helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(aboutAction);
helpMenu->addAction(aboutQtAction);
}
void MainWindow::createContextMenu()
{
//任何窗口都可以添加一个与之相连的QActions列表
spreadsheet->addAction(cutAction);
spreadsheet->addAction(copyAction);
spreadsheet->addAction(pasteAction);
//将窗口的上下文菜单策略设置为一个显示动作的上下文菜单
spreadsheet->setContextMenuPolicy(Qt::ActionsContextMenu);
}
void MainWindow::createToolBars()
{
//增加一个toolbar toolbar是不可见的 但是有分隔符
//toolbai并不是系统自带的!!
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()
{
//设置所能包含的最大字符字数,
locationLabel = new QLabel(" Q999 ");
//居中对齐
/*Qt::AlignLeft 左对齐
Qt::AlignRight 右对齐
Qt::AlignHCenter 居中
Qt::AlignTop 顶部对齐
Qt::AlignBottom 底部对齐*/
//定位指示器
locationLabel->setAlignment(Qt::AlignHCenter);
//设置Label的最小大小
locationLabel->setMinimumSize(locationLabel->sizeHint());
//单位格公式指示器
formulaLabel = new QLabel;
//缩进长度
formulaLabel->setIndent(20);
statusBar()->addWidget(locationLabel);
//第二个参数指定伸展因子
statusBar()->addWidget(formulaLabel,1);
//当移动的时候就可以发出信号
connect(spreadsheet, SIGNAL(currentCellChanged(int, int, int, int)),
this, SLOT(updateStatusBar()));
//对*的改变
//其实使用cellChanged也是可以的 因为它是cell的改变
//使用itemChanged()也是可以的 而
connect(spreadsheet, SIGNAL(modified()),
this, SLOT(spreadsheetModified()));
updateStatusBar();
}
void MainWindow::readSettings()
{
QSettings settings("Software Inc.", "Spreadsheet");
restoreGeometry(settings.value("geometry").toByteArray());
recentFiles = settings.value("recentFiles").toStringList();
updateRecentFileActions();
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());
}
bool MainWindow::okToContinue()
{
if (isWindowModified()) {
//QMessageBox提供了许多标准按钮,按ESC退出
//QMessageBox还提供了information、question()、critical()函数,
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;
}
bool MainWindow::loadFile(const QString &fileName)
{
if (!spreadsheet->readFile(fileName)) {
//维持两秒 状态懒得临时提醒
//之前的QAction可以直接用newAction->setStatusTip()
statusBar()->showMessage(tr("Loading canceled"), 2000);
return false;
}
setCurrentFile(fileName);
statusBar()->showMessage(tr("File loaded"), 2000);
return true;
}
bool MainWindow::saveFile(const QString &fileName)
{
if (!spreadsheet->writeFile(fileName)) {
statusBar()->showMessage(tr("Saving canceled"), 2000);
return false;
}
setCurrentFile(fileName);
statusBar()->showMessage(tr("File saved"), 2000);
return true;
}
//更新窗口的标题
//*的妙用
void MainWindow::setCurrentFile(const QString &fileName)
{
curFile = fileName;
setWindowModified(false);
QString shownName = tr("Untitled");
if (!curFile.isEmpty()) {
shownName = strippedName(curFile);
recentFiles.removeAll(curFile);
recentFiles.prepend(curFile);
///recentFiles.append()是在末尾插入数据
///prepend是在头节点处插入数据
///push_back push_front与上述操作一致 只不过是由STL提供的
updateRecentFileActions();
}
setWindowTitle(tr("%1[*] - %2").arg(shownName)
.arg(tr("Spreadsheet")));
}
void MainWindow::updateRecentFileActions()
{
QStringList::Iterator i;
for(i = recentFiles.begin();i != recentFiles.end();)
{
if(!QFile::exists(*i))
{
recentFiles.erase(i++);
}
else
{
i++;
}
}
/*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());
}
QString MainWindow::strippedName(const QString &fullFileName)
{
return QFileInfo(fullFileName).fileName();
}