C++ Qt的文字批改器今天初步呢,我們就初步用Qt做兩個比照有用的東西,這一篇我們首要根究下文字批改器的結束。
首要我們來看下我們的大致佈局:
class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(); protected: void closeEvent(QCloseEvent *event);關於全部定義的訊號和槽的類,在類定義初步處的O_OBJECT巨集都是必需的。
private slots: void newFile(); void open(); bool save(); bool saveAs(); void about(); void documentWasModified();私有槽中包含了建立新檔案、翻開檔案、保管檔案以及about。當然了我們還有一個在程式中最重要的函式documentWasModified(),結束的共ing功用是區分是不是檔案被批改。
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); QTextEdit *textEdit; QString curFile; QMenu *fileMenu; QMenu *editMenu; QMenu *formMenu; QMenu *helpMenu; QToolBar *fileToolBar; QToolBar *editToolBar; QAction *newAct; QAction *openAct; QAction *saveAct; QAction *saveAsAct; QAction *exitAct; QAction *automaticAct; QAction *typefaceAct; QAction *cutAct; QAction *copyAct; QAction *pasteAct; QAction *aboutAct; QAction *aboutQtAct; };在這裡邊定義了在程式中用到的全部類的例項,createActions();createMenus(); createToolBars();createStatusBar();用於建立使用者介面。readSetting()用於恢復使用者從前的設定。下面我們就來逐一看看詳細結束:
MainWindow::MainWindow() { textEdit = new QTextEdit; setCentralWidget(textEdit); createActions(); createMenus(); createToolBars(); createStatusBar(); readSettings(); connect(textEdit->document(), SIGNAL(contentsChanged()), this, SLOT(documentWasModified)); setCurrentFile(""); }我們的佈局函式首要建立一個文字框例項,然後設定中心窗體,再者呼叫使用者介面即可結束。
void MainWindow::closeEvent(QCloseEvent *event) { if(maybeSave()) { writeSettings(); event->accept(); } else { event->ignore(); } }closeEvent()函式結束功用:在使用者檢驗退出時警告使用者關於未保管的批改資訊。
void MainWindow::newFile() { if(maybeSave()) { textEdit->clear(); setCurrentFile(""); } }newFile函式結束功用:首要區分其時檔案是不是已保管,如果未保管先保管然後建立新檔案。
void MainWindow::open() { if(maybeSave()) { QString fileName = QFileDialog::getOpenFileName(this); if(!fileName.isEmpty()) loadFile(fileName); } }open()函式結束功用:首要區分其時檔案是不是已保管,如果未保管則先保管,然後通過QFileDialog的靜態函式getOpenFileName()獲取檔案目錄,翻開。
bool MainWindow::save() { if(curFile.isEmpty()) { return saveAs(); } else { return saveFile(curFile); } } bool MainWindow::saveAs() { QString fileName = QFileDialog::getSaveFileName(this); if(fileName.isEmpty()) return false; return saveFile(fileName); }save() slot在使用者點選File Save選單項時被呼叫。如果使用者還沒為檔案供應一個名字,則呼叫saveAs(),否則呼叫saveFile()來保管檔案。
void MainWindow::about() { QMessageBox::about(this, tr("About Application"), tr("TheApplicationexample created byYzs ")); }about()函式對話方塊通過QMessageBox::about()靜態函式結束
void MainWindow::documentWasModified() { setWindowModified(textEdit->document()->isModified()); }documentWasModified() slot在QTextEdit中的文字被改動時被呼叫。我們呼叫QWidget::setWindowModified()來是標題欄閃現檔案已被批改(閃現個*號)。
void MainWindow::createActions() { newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); newAct->setShortcut(tr("Ctrl+N")); newAct->setStatusTip(tr("Create a new file")); connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); openAct->setShortcut(tr("Ctrl+O")); openAct->setStatusTip(tr("Open an existing file")); connect(openAct, SIGNAL(triggered()), this, SLOT(open())); saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); saveAct->setShortcut(tr("Ctrl+S")); saveAct->setStatusTip(tr("Save a file")); connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); saveAsAct = new QAction(tr("Save &As..."), this); saveAsAct->setStatusTip(tr("Save the file under a new name")); connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); exitAct = new QAction(tr("E&xit"), this); exitAct->setShortcut(tr("Ctrl+Q")); exitAct->setStatusTip(tr("Exit the application")); connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); automaticAct = new QAction(tr("&Automatic"), this); automaticAct->setChecked(false); automaticAct->setStatusTip(tr("Automatic the file")); connect(automaticAct, SIGNAL(triggered()), this, SLOT(automatic())); typefaceAct = new QAction(tr("&Typeface"), this); typefaceAct->setStatusTip(tr("typefaceAct")); connect(typefaceAct, SIGNAL(triggered()), this, SLOT(typeface())); cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this); cutAct->setShortcut(tr("Ctrl+X")); cutAct->setStatusTip(tr("Cut the current selection's contents to the clipboard")); connect(cutAct, SIGNAL(triggered()), this, SLOT(cut())); copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this); copyAct->setShortcut(tr("Ctrl+C")); copyAct->setStatusTip(tr("Copy the current selection's contents to clipboard")); connect(copyAct, SIGNAL(triggered()), this, SLOT(copy())); pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this); pasteAct->setShortcut(tr("Ctrl+V")); pasteAct->setStatusTip(tr("Paste the current selection's contents to clipboard")); connect(pasteAct, SIGNAL(triggered()), this, SLOT(paste())); aboutAct = new QAction(tr("&About"), this); aboutAct->setStatusTip(tr("Show the application's About box")); connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); aboutQtAct = new QAction(tr("About &Qt"), this); aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); cutAct->setEnabled(false); copyAct->setEnabled(false); connect(textEdit, SIGNAL(copyAvailable(bool)), cutAct, SLOT(setEnabled(bool))); connect(textEdit, SIGNAL(copyAvailable(bool)), copyAct, SLOT(setEnabled(bool))); }QAction是一個代表使用者舉動的方針,例如,保管檔案或彈出對話方塊。一個action可以被放入QMenu或QToolBar中,也可以被放入其它過載了QWidget::actionEvent()的widget中。一個action有一個用於描寫它作用的文字,當用戶觸發這個action時,它宣告triggered()訊號。我們將這個訊號連線到一個slot上以結束實在的功用。Edit Cut和Edit Copy action必須在QTextEdit包含已選擇的文字時才有用。在默許情況下我們將它們禁用並將QTextEdit::copyAvailable()訊號連線到QAction::setEnabled() slot上,以確保在文字批改器中沒有選擇文字時著兩個舉動無效。C++ Qt的文字批改器緊接著我們的上一篇博文Qt之文字批改器(上)我們繼續我哦們的文字批改器之旅。
void MainWindow::createMenus() { fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(newAct); fileMenu->addAction(openAct); fileMenu->addAction(saveAct); fileMenu->addAction(saveAsAct); fileMenu->addSeparator(); fileMenu->addAction(exitAct); editMenu = menuBar()->addMenu(tr("&Edit")); editMenu->addAction(cutAct); editMenu->addAction(copyAct); editMenu->addAction(pasteAct); menuBar()->addSeparator(); formMenu = menuBar()->addMenu(tr("&Form")); formMenu->addAction(automaticAct); formMenu->addAction(typefaceAct); menuBar()->addSeparator(); helpMenu = menuBar()->addMenu(tr("&Help")); helpMenu->addAction(aboutAct); helpMenu->addAction(aboutQtAct); }建立選單,以及進行計劃。
void MainWindow::createToolBars() { fileToolBar = addToolBar(tr("File")); fileToolBar->addAction(newAct); fileToolBar->addAction(openAct); fileToolBar->addAction(saveAct); editToolBar = addToolBar(tr("Edit")); editToolBar->addAction(cutAct); editToolBar->addAction(copyAct); editToolBar->addAction(pasteAct); }建立東西Bar,並對其新增Action.
void MainWindow::createStatusBar() { statusBar()->showMessage(tr("Ready")); }QMainWindow::statusBar()回來指向視窗的QStatusBar widget的指標
void MainWindow::readSettings() { QSettings settings("Yzs", "Application Example"); QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); QSize size = settings.value("size", QSize(400, 400)).toSize(); resize(size); move(pos); } void MainWindow::writeSettings() { QSettings settings("Yzs", "Application Example"); settings.setValue("pos", pos()); settings.setValue("size", size()); }運用QSettings類的結束了運用,關於這個類的詳細用法可以參看我的另一篇博文,我有詳盡的說明。
bool MainWindow::maybeSave() { if(textEdit->document()->isModified()) { int ret = QMessageBox::warning(this, tr("Application"), tr("The document has been modified.\n" "Do you want to save your changes?"), QMessageBox::Yes QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel QMessageBox::Escape); if(ret == QMessageBox::Yes) return save(); else if(ret == QMessageBox::Cancel) return false; } return true; } 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); QApplication::setOverrideCursor(Qt::WaitCursor); textEdit->setPlainText(in.readAll()); QApplication::restoreOverrideCursor(); setCurrentFile(fileName); statusBar()->showMessage(tr("File loaded"), 2000); } bool MainWindow::saveFile(const QString &fileName) { QFile file(fileName); if(!file.open(QFile::WriteOnly QFile::Text)) { QMessageBox::warning(this, tr("Application"), tr("Cannot write file %1:\n%2.") .arg(fileName).arg(file.errorString())); return false; } QTextStream out(&file); QApplication::setOverrideCursor(Qt::WaitCursor); out QApplication::restoreOverrideCursor(); setCurrentFile(fileName); statusBar()->showMessage(tr("File saved"), 2000); return false; }maybeSave()函式結束區分檔案是不是已保管,loadFile()函式結束對檔案的載入,saveFile()函式結束對檔案的保管
void MainWindow::setCurrentFile(const QString &fileName) { curFile = fileName; textEdit->document()->setModified(false); setWindowModified(false); QString shownName; if(curFile.isEmpty()) shownName = "untitled.txt"; else shownName = strippedName(curFile); setWindowTitle(tr("%1[*] - %2").arg(shownName).arg(tr("Application"))); }setCurrentFile()函式在一個檔案被裝載、保管或使用者初步批改新檔案時被呼叫,
用於復位一些變數的情況。我們更新curFile變數,清0 QTextDocument::modified標誌和與之有關的
QWidget::windowModified標誌,更新視窗的標題以包含新檔名。
QString MainWindow::strippedName(const QString &fullFileName) { return QFileInfo(fullFileName).fileName(); }strippedName()函式用於批改檔名為較短的絕對路徑。
我們的詳細函式描寫現已結束了,下面就只剩下我們的main函數了
int main(int argc, char *argv[]) { Q_INIT_RESOURCE(application); QApplication app(argc, argv); MainWindow mainWin; mainWin.show(); return app.exec(); }OK了,但還有一點我們不要忘了,我們在程式中運用了資原始檔,我們的影象檔案都是儲存在資原始檔中的,我們新建資原始檔application.qrc,然後在application.pro檔案中需參與RESOURCES = application.qrc,資原始檔的詳細內容如下:
images/copy.png images/cut.png images/new.png images/open.png images/paste.png images/save.png 這樣我們就實在在正的結束了一個簡略的文字批改器了,感觸怎麼,全部都是那樣的清楚。