1.類定義
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
protected:
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
private slots:
void newFile();
void open();
bool save();
bool saveAs();
void about();
void documentWasModified();
private:
void createActions();
void createMenus();
void createToolBars();
void createStatusBar();
void readSettings();
void writeSettings();
bool maybeSave();
void loadFile(const QString &fileName);
bool saveFile(const QString &fileName);
void setCurrentFile(const QString &fileName);
QString strippedName(const QString &fullFileName);
QPlainTextEdit *textEdit;
QString curFile;
QMenu *fileMenu;
QMenu *editMenu;
QMenu *helpMenu;
QToolBar *fileToolBar;
QToolBar *editToolBar;
QAction *newAct;
QAction *openAct;
QAction *saveAct;
QAction *saveAsAct;
QAction *exitAct;
QAction *cutAct;
QAction *copyAct;<pre name="code" class="cpp">MainWindow::MainWindow()
{
textEdit = new QPlainTextEdit;
setCentralWidget(textEdit);
createActions();
createMenus();
createToolBars();
createStatusBar();
readSettings();
connect(textEdit->document(), SIGNAL(contentsChanged()),
this, SLOT(documentWasModified()));
setCurrentFile("");
setUnifiedTitleAndToolBarOnMac(true);
}
QAction *pasteAct; QAction *aboutAct; QAction *aboutQtAct;};
QWidget::closeEvent()用於監聽用戶關閉動作,提醒沒有保存修改.
#include <QtWidgets>
#include "mainwindow.h"
QtWidgets裏面包含Qt Core等類,爲什麼不把QtWidgets包含在mainwindow.h裏呢?因爲頭文件太大了,會影響性能.
MainWindow::MainWindow()
{
textEdit = new QPlainTextEdit;
setCentralWidget(textEdit);
createActions();
createMenus();
createToolBars();
createStatusBar();
readSettings();
connect(textEdit->document(), SIGNAL(contentsChanged()),
this, SLOT(documentWasModified()));
setCurrentFile("");
setUnifiedTitleAndToolBarOnMac(true);
}
QMainWindow::setCentralWidget()用於告訴widget這個控件將佔用windows中間區域在tool bars和status bars中間
void MainWindow::closeEvent(QCloseEvent *event)
{
if (maybeSave()) {
writeSettings();
event->accept();
} else {
event->ignore();
}
}
用戶嘗試關閉窗口的時候,maybesave詢問用戶是否存儲變化.
void MainWindow::newFile()
{
if (maybeSave()) {
textEdit->clear();
setCurrentFile("");
}
}
清空當前的東西,詢問是否存儲.
void MainWindow::open()
{
if (maybeSave()) {
QString fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty())
loadFile(fileName);
}
}
這些打開啊實際上就是要一個文件路徑.
bool MainWindow::save()
{
if (curFile.isEmpty()) {
return saveAs();
} else {
return saveFile(curFile);
}
}
如果沒提供名字,就saveAs()
bool MainWindow::saveAs()
{
QFileDialog dialog(this);
dialog.setWindowModality(Qt::WindowModal);
dialog.setAcceptMode(QFileDialog::AcceptSave);
QStringList files;
if (dialog.exec())
files = dialog.selectedFiles();
else
return false;
return saveFile(files.at(0));
}
Qt::WindowModal 阻塞自己的父輩.點確定得到一個文件路徑,點取消返回空,什麼都不做.
QMessageBox::about定義了一個靜態顯示關於的方便函數.使用tr()用於所有可見的地方,是個非常好的習慣,因爲可以用工具翻譯.
QAction就是一個下拉菜單裏的項,是一個動作,可以放在QMenu和QToolBar裏面,或者任意實現了QWidget::actionEvent()函數的Widget裏面
可以顯示爲菜單,圖標,快捷鍵,tip,狀態欄等方式,點了之後發送Triggered()信號
cutAct->setEnabled(false);
copyAct->setEnabled(false);
connect(textEdit, SIGNAL(copyAvailable(bool)),
cutAct, SLOT(setEnabled(bool)));
connect(textEdit, SIGNAL(copyAvailable(bool)),
copyAct, SLOT(setEnabled(bool)));
當你選中文字的時候發射copyAvailable(true),這個時候複製和剪切菜單就不虛,相反就是虛的.
創建了Action以後還有一個關鍵點是添加到Menu或者toolbar上面,用addAction方法就好了!
void MainWindow::readSettings()
{
QSettings settings("QtProject", "Application Example");
QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
QSize size = settings.value("size", QSize(400, 400)).toSize();
resize(size);
move(pos);
}
從QSetting裏面讀取獨立的用戶設置,然後用QWidget::resize()在QWidget::move()之前bool MainWindow::maybeSave()
{
if (textEdit->document()->isModified()) {
QMessageBox::StandardButton ret;
ret = QMessageBox::warning(this, tr("Application"),
tr("The document has been modified.\n"
"Do you want to save your changes?"),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
if (ret == QMessageBox::Save)
return save();
else if (ret == QMessageBox::Cancel)
return false;
}
return true;
}
如果文檔被修改了,就彈出詢問對話框,不然就直接返回false
void MainWindow::loadFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Application"),
tr("Cannot read file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return;
}
QTextStream in(&file);
#ifndef QT_NO_CURSOR
QApplication::setOverrideCursor(Qt::WaitCursor);
#endif
textEdit->setPlainText(in.readAll());
#ifndef QT_NO_CURSOR
QApplication::restoreOverrideCursor();
#endif
setCurrentFile(fileName);
statusBar()->showMessage(tr("File loaded"), 2000);
}
對文件的操作都類似,先要通過名字得到文件描述符,然後在標準流來操作文件.
QTextStream 自動地轉化8bit數據到Unicode QString,並且支持多種內碼,默認支持 Latin-1
因爲讀取可能要花些時間,把光標弄成等待的形狀.
void MainWindow::setCurrentFile(const QString &fileName)
{
curFile = fileName;
textEdit->document()->setModified(false);
setWindowModified(false);
QString shownName = curFile;
if (curFile.isEmpty())
shownName = "untitled.txt";
setWindowFilePath(shownName);
}
setModified用於設置標誌,但這個標誌是自動的嗎?你編輯文本的時候,肯定有一個信號吧,那麼槽的話估計也要修改這個標誌的.