C++ Qt的文本批改器
操作方法
- 01
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 这样我们就实在在正的结束了一个简略的文本批改器了,感触怎么,全部都是那样的清楚。