NotePad使用主窗口做爲頂層窗口組件,使用QMainWindow做爲基類,QMainWindow內部封裝了菜單欄、工具欄、中央組件、停靠組件、狀態欄等。QMainWindow內置了佈局管理器,基本的組件佈局以下:數據庫
使用二階構造模式構建NotePad界面。架構
MainWindow::MainWindow() { resize(800, 600); } MainWindow::~MainWindow() { } MainWindow* MainWindow::newInstance() { MainWindow* ret = new MainWindow(); if((ret == NULL) || (!ret->construct())) { delete ret; ret = NULL; } return ret; } bool MainWindow::construct() { bool ret = true; ret = ret && initMenuBar();//菜單欄構建 ret = ret && initToolBar();//工具欄構建 ret = ret && initStatusBar();//狀態欄構建 ret = ret && initMainEditor();//中央組件構建 return ret; }
QT中提供了預約義的與菜單相關的類組件,菜單欄QMenuBar,下拉菜單QMenu,菜單項QAction。app
QMenuBar* mb = menuBar();框架
QMenu* menu = new QMenu("File(&F)");編輯器
QAction *action = new QAction(text, NULL);ide
menu->addAction(action);函數
mb->addMenu(menu);工具
快捷鍵設置佈局
action->setShortcut(QKeySequence(KEY));字體
QKeySequence是QT中與快捷鍵相關的類,KEY是QT中表明鍵值的常量。
NotePad菜單欄共有文件、編輯、格式、查看、幫助五組下拉菜單,每組下拉菜單使用一個函數構建。
bool MainWindow::initMenuBar() { bool ret = true; QMenuBar *mb = menuBar(); ret = ret && initFileMenu(mb); ret = ret && initEditMenu(mb); ret = ret && initFormatMenu(mb); ret = ret && initViewMenu(mb); ret = ret && initHelpMenu(mb); return ret; } bool MainWindow::initFileMenu(QMenuBar *mb) { QMenu *menu = new QMenu("File(&F)"); bool ret = (menu != NULL); if(ret) { QAction *action = NULL; ret = ret && makeAction(action, "New(&N)", Qt::CTRL + Qt::Key_N); if(ret) { menu->addAction(action); } ret = ret && makeAction(action, "Open(&O)", Qt::CTRL + Qt::Key_O); if(ret) { menu->addAction(action); } ret = ret && makeAction(action, "Save(&S)", Qt::CTRL + Qt::Key_S); if(ret) { menu->addAction(action); } ret = ret && makeAction(action, "Save As(&A)", 0); if(ret) { menu->addAction(action); } menu->addSeparator(); ret = ret && makeAction(action, "Page Setting(&U)", 0); if(ret) { menu->addAction(action); } ret = ret && makeAction(action, "Print(&P)", Qt::CTRL + Qt::Key_P); if(ret) { menu->addAction(action); } menu->addSeparator(); ret = ret && makeAction(action, "Exit(&X)", 0); if(ret) { menu->addAction(action); } } if(ret) { mb->addMenu(menu); } else { delete menu; } return ret; } bool MainWindow::makeAction(QAction *&action, QString text, int key) { bool ret = true; action = new QAction(text, NULL); if(action != NULL) { action->setShortcut(QKeySequence(key)); } else { ret = false; } return ret; } bool MainWindow::initEditMenu(QMenuBar *mb) { QMenu *menu = new QMenu("Edit(&E)", NULL); bool ret = (menu != NULL); if(ret) { QAction *action = NULL; ret = ret && makeAction(action, "Undo(&U)", Qt::CTRL + Qt::Key_Z); if(ret) { menu->addAction(action); } menu->addSeparator(); ret = ret && makeAction(action, "Cut(&T)", Qt::CTRL + Qt::Key_X); if(ret) { menu->addAction(action); } ret = ret && makeAction(action, "Copy(&C)", Qt::CTRL + Qt::Key_C); if(ret) { menu->addAction(action); } ret = ret && makeAction(action, "Paste(&P)", Qt::CTRL + Qt::Key_V); if(ret) { menu->addAction(action); } ret = ret && makeAction(action, "Delete(&L)", Qt::Key_Delete); if(ret) { menu->addAction(action); } menu->addSeparator(); ret = ret && makeAction(action, "Find(&F)", Qt::CTRL + Qt::Key_F); if(ret) { menu->addAction(action); } ret = ret && makeAction(action, "Find Next(&N)", Qt::Key_F3); if(ret) { menu->addAction(action); } ret = ret && makeAction(action, "Replace(&R)", Qt::CTRL + Qt::Key_H); if(ret) { menu->addAction(action); } ret = ret && makeAction(action, "Goto(&G)", Qt::CTRL + Qt::Key_G); if(ret) { menu->addAction(action); } menu->addSeparator(); ret = ret && makeAction(action, "All(&A)", Qt::CTRL + Qt::Key_A); if(ret) { menu->addAction(action); } ret = ret && makeAction(action, "Time/Date(&D)", Qt::Key_F5); if(ret) { menu->addAction(action); } } if(ret) { mb->addMenu(menu); } else { delete menu; } return ret; } bool MainWindow::initFormatMenu(QMenuBar *mb) { QMenu *menu = new QMenu("Format(&O)", NULL); bool ret = (menu != NULL); if(ret) { QAction *action = NULL; ret = ret && makeAction(action, "Auto Wrap(&W)", 0); if(ret) { menu->addAction(action); } menu->addSeparator(); ret = ret && makeAction(action, "Font(&F)", 0); if(ret) { menu->addAction(action); } } if(ret) { mb->addMenu(menu); } else { delete menu; } return ret; } bool MainWindow::initViewMenu(QMenuBar *mb) { QMenu *menu = new QMenu("View(&V)", NULL); bool ret = (menu != NULL); if(ret) { QAction *action = NULL; ret = ret && makeAction(action, "Status(&S)", 0); if(ret) { menu->addAction(action); } } if(ret) { mb->addMenu(menu); } else { delete menu; } return ret; } bool MainWindow::initHelpMenu(QMenuBar *mb) { QMenu *menu = new QMenu("Help(&H)", NULL); bool ret = (menu != NULL); if(ret) { QAction *action = NULL; ret = ret && makeAction(action, "Help(&H)", 0); if(ret) { menu->addAction(action); } menu->addSeparator(); ret = ret && makeAction(action, "About NotePad(&A)", 0); if(ret) { menu->addAction(action); } } if(ret) { mb->addMenu(menu); } else { delete menu; } return ret; }
工具欄是應用程序中集成各類功能使用快捷方式的區域,不是應用程序必須存在的組件,工具欄的元素能夠是各類窗口組件,但一般以圖標按鈕的方式存在。
QT中提供了預約義的工具欄相關組件,工具欄QToolBar和快捷項QAction。
//建立工具欄
QToolBar *tb = addToolBar("ToolBar");
//建立工具欄選項
QAction *action = new QAction("", NULL);
action->setToolTip(「Open」);
action->setIcon(QIcon(「/res/pic/open.png」));
//將工具欄選項加入工具欄
tb->addAction(action);
void setFloatable(bool floatable)設置工具欄爲浮動
void setMovable(bool movable)設置工具欄爲可移動
void setIconSize(const QSize & iconSize)設置工具欄的圖標大小
QTollBar組件中能夠加入QT中的任意QWidget組件。
將菜單欄中的主要經常使用功能添加到工具欄中,按照功能所屬的菜單欄進行分組建立。
bool MainWindow::initToolBar() { bool ret = true; QToolBar *tb = addToolBar("ToolBar"); tb->setMovable(false); tb->setIconSize(QSize(16, 16)); ret = ret && initFileToolItem(tb);//建立文件菜單欄的功能到工具欄 ret = ret && initEditToolItem(tb);//建立編輯菜單欄到工具欄 ret = ret && initFormatToolItem(tb);//建立格式菜單欄到工具欄 ret = ret && initViewToolItem(tb);//建立查看菜單欄到工具欄 return ret; } bool MainWindow::initFileToolItem(QToolBar *tb) { bool ret = true; QAction *action = NULL; ret = ret && makeAction(action, "New", ":/res/pic/new.png"); if( ret ) { tb->addAction(action); } ret = ret && makeAction(action, "Open", ":/res/pic/open.png"); if( ret ) { tb->addAction(action); } ret = ret && makeAction(action, "Save", ":/res/pic/save.png"); if( ret ) { tb->addAction(action); } ret = ret && makeAction(action, "SaveAs", ":/res/pic/saveas.png"); if( ret ) { tb->addAction(action); } ret = ret && makeAction(action, "Print", ":/res/pic/print.png"); if( ret ) { tb->addAction(action); } tb->addSeparator(); return ret; } bool MainWindow::initEditToolItem(QToolBar* tb) { bool ret = true; QAction *action = NULL; ret = ret && makeAction(action, "Undo", ":/res/pic/undo.png"); if( ret ) { tb->addAction(action); } ret = ret && makeAction(action, "Redo", ":/res/pic/redo.png"); if( ret ) { tb->addAction(action); } ret = ret && makeAction(action, "Cut", ":/res/pic/cut.png"); if( ret ) { tb->addAction(action); } ret = ret && makeAction(action, "Copy", ":/res/pic/copy.png"); if( ret ) { tb->addAction(action); } ret = ret && makeAction(action, "Paste", ":/res/pic/paste.png"); if( ret ) { tb->addAction(action); } ret = ret && makeAction(action, "Find", ":/res/pic/find.png"); if( ret ) { tb->addAction(action); } ret = ret && makeAction(action, "Replace", ":/res/pic/replace.png"); if( ret ) { tb->addAction(action); } ret = ret && makeAction(action, "Goto", ":/res/pic/goto.png"); if( ret ) { tb->addAction(action); } tb->addSeparator(); return ret; } bool MainWindow::initFormatToolItem(QToolBar* tb) { bool ret = true; QAction *action = NULL; ret = ret && makeAction(action, "Auto Wrap", ":/res/pic/wrap.png"); if( ret ) { tb->addAction(action); } ret = ret && makeAction(action, "Font", ":/res/pic/font.png"); if( ret ) { tb->addAction(action); } tb->addSeparator(); return ret; } bool MainWindow::initViewToolItem(QToolBar* tb) { bool ret = true; QAction *action = NULL; ret = ret && makeAction(action, "ToolBar", ":/res/pic/tool.png"); if( ret ) { tb->addAction(action); } ret = ret && makeAction(action, "Status", ":/res/pic/status.png"); if( ret ) { tb->addAction(action); } return ret; } bool MainWindow::makeAction(QAction*& action, QString tip, QString icon) { bool ret = true; action = new QAction("", NULL); if( action != NULL ) { action->setToolTip(tip); action->setIcon(QIcon(icon)); } else { ret = false; } return ret; }
狀態欄是應用程序中輸出簡要信息的區域,通常位於窗口的底部。狀態欄顯示的消息類型以下:
A、實時消息,如當前程序狀態
B、永久消息,如程序版本,開發機構
C、進度消息,進度顯示
QT中提供了預約義的狀態欄相關組件狀態欄QStatusBar,QStatusBar是容器型組件,能夠是任意組件QWidget的父組件。
QT狀態欄的通常設計原則:
A、狀態欄左邊區域用於輸出實時消息
B、狀態欄右邊區域用於輸出永久消息
所以,addWidget函數用於在狀態欄左邊區域添加組件,addPermanentWidget函數用於在狀態欄右邊區域添加組件。
bool MainWindow::initStatusBar() { bool ret = true; QStatusBar *sb = statusBar(); QLabel *label = new QLabel("CopyRight @Scorpio Studio"); if(label != NULL) { label->setMinimumWidth(150); label->setAlignment(Qt::AlignCenter); sb->addPermanentWidget(label); } else { ret = false; } return ret; }
中央組件是多行文本編組件,使用QPlainTextEdit組件。
bool MainWindow::initMainEditor() { bool ret = true; //設置mainEditor的父組件 mainEditor.setParent(this); //設置中央組件爲mainEditor setCentralWidget(&mainEditor); //設置mainEditor的背景色爲豆沙綠 QPalette p = mainEditor.palette(); p.setColor(QPalette::Base, QColor(204, 232, 207)); mainEditor.setPalette(p); return ret; }
考慮到用戶界面與業務邏輯代碼的分離,槽函數實現須要與界面實現向分離,槽函數在新建MainwWindowSlots.cpp文件中實現,界面文件名稱改成MainWindowUI.cpp。
菜單欄與工具欄中的QAction對象在鼠標點擊後會發送triggered()信號,經過信號與槽機制能夠實現對QAction對象的操做的處理。
connect(action, SIGNAL(triggered()), this, SLOT(slotfunction));
在QAction對象建立的時候鏈接信號與槽函數。
建立文件對話框:
QString MainWindow::createFileDialog(QFileDialog::AcceptMode mode, QString title) { QString ret = ""; QFileDialog filedialog(this); QStringList filter; filter.append("Text Files (*.txt)"); filter.append("All Files (*.*)"); filedialog.setWindowTitle(title); filedialog.setAcceptMode(mode); filedialog.setNameFilters(filter); if(mode == QFileDialog::AcceptOpen) { filedialog.setFileMode(QFileDialog::ExistingFile); } if(filedialog.exec() == QFileDialog::Accepted) { ret = filedialog.selectedFiles()[0]; } return ret; }
錯誤消息提示框:
void MainWindow::showErrorMessage(const QString& title, const QString & text, QMessageBox::StandardButtons buttons) { QMessageBox::critical(this, title, text, buttons); }
打開文件:
void MainWindow::onFileOpen() { QString path = createFileDialog(QFileDialog::AcceptOpen, "Open"); if(path != "") { QFile file(path); if(file.open(QIODevice::ReadOnly | QIODevice::Text)) { mainEditor.setPlainText(QString(file.readAll())); file.close(); m_filepath = path; setWindowTitle("NotePad - [" + m_filepath + "]"); } else { showErrorMessage(QString("Error"), QString("Open file error: " + m_filepath), QMessageBox::Ok); } } }
保存文件:
void MainWindow::onFileSave() { if(m_filepath == "") { m_filepath = createFileDialog(QFileDialog::AcceptSave, "Save"); } if(m_filepath != "") { QFile file(m_filepath); if(file.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream out(&file); out << mainEditor.toPlainText(); file.close(); setWindowTitle("NotePad - [ " + m_filepath + " ]"); } else { showErrorMessage(QString("Error"), QString("Save file error: " + m_filepath), QMessageBox::Ok); m_filepath = ""; } } }
另存文件:
void MainWindow::onFileSaveAs() { QString path = createFileDialog(QFileDialog::AcceptSave, "Save As"); if(path != "") { QFile file(path); if(file.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream out(&file); out << mainEditor.toPlainText(); file.close(); m_filepath = path; setWindowTitle("NotePad - [ " + m_filepath + " ]"); } else { showErrorMessage(QString("Error"), QString("Save as error: " + m_filepath), QMessageBox::Ok); } } }
建立新文件:
void MainWindow::onFileNew() { preTextChanged(); if(!m_isTextChanged) { mainEditor.clear(); setWindowTitle("NotePad - [New ]"); m_filepath = ""; m_isTextChanged = false; } }
QPlainTextEdit編輯器組件提供了編輯交互功能接口。
QPlainTextEdit內置的信號以下:
void textChanged()
void copyAvailable(bool yes)
void redoAvailable(bool available)
void undoAvailable(bool available)
void cursorPositionChanged()
void modificationChanged(bool changed)
QPlainTextEdit內置的槽函數以下:
void copy()
void cut()
void paste()
void redo()
void selectAll()
void undo()
將菜單欄、工具欄中的copy、cut、paste、redo、undo等編輯操做QAction對象的triggered()信號鏈接到QPlainTextEdit對象的相應操做的槽函數,便可實現編輯操做。
connect(action, SIGNAL(triggered(bool)), &mainEditor, SLOT(undo());
connect(action, SIGNAL(triggered()), &mainEditor, SLOT(cut()));
connect(action, SIGNAL(triggered()), &mainEditor, SLOT(copy()));
connect(action, SIGNAL(triggered()), &mainEditor, SLOT(paste());
工具欄QAction對象的界面狀態的設置
在建立Copy、Undo、Redo的QAction對象時設置爲不可用狀態。
將QPlainTextEdit對象的copyAvailable、undoAvailable、redoAvailable信號鏈接到自定義槽函數。
connect(&mainEditor, SIGNAL(copyAvailable(bool)), this, SLOT(onCopyAvailable(bool)));
connect(&mainEditor, SIGNAL(undoAvailable(bool)), this, SLOT(onUndoAvailable(bool)));
connect(&mainEditor, SIGNAL(redoAvailable(bool)), this, SLOT(onRedoAvailable(bool)));
在自定義槽函數中根據信號的參數available設置QAction對象的狀態
void MainWindow::onCopyAvailable(bool available) { findMenuBarItem("Copy")->setEnabled(available); findMenuBarItem("Cut")->setEnabled(available); findToolBarItem("Copy")->setEnabled(available); findToolBarItem("Cut")->setEnabled(available); } void MainWindow::onUndoAvailable(bool available) { findMenuBarItem("Undo")->setEnabled(available); findToolBarItem("Undo")->setEnabled(available); } void MainWindow::onRedoAvailable(bool available) { findToolBarItem("Redo")->setEnabled(available); }
拖放一個文件進入窗口時將觸發拖放事件,QWidget對象都能處理拖放事件。
設置窗口支持拖放事件:
在構造函數調用setAcceptDrops(true);
重寫拖放事件的處理函數:
void dragEnterEvent(QDragEnterEvent *event);
void dropEvent(QDropEvent *event);
默認狀況下,QPlainTextEdit接受來自其餘應用程序拖拽來的文本,把文件名顯示出來。因爲DropEvent是由子組件向父組件傳播的,經過禁止QPlainTextEdit的DropEvent,主窗口能夠獲取DropEvent,MainWindow中就能夠處理DropEvent。
在MainWwindow構造函數中須要禁止QPlainTextEdit接受DropEvent,容許MainWindow接受DropEvent。
mainEditor.setAcceptDrops(false);
setAcceptDrops(true);
重寫事件處理函數:
void MainWindow::dragEnterEvent(QDragEnterEvent *event) { if(event->mimeData()->hasFormat("text/uri-list")) { event->acceptProposedAction(); } else { event->ignore(); } } void MainWindow::dropEvent(QDropEvent *event) { if(event->mimeData()->hasUrls()) { QList<QUrl> list = event->mimeData()->urls(); QString path = list[0].toLocalFile(); QFileInfo fi(path); if( fi.isFile() ) { preTextChanged(); if(!m_isTextChanged) { loadFile(path); } } else { showMessage(this, QMessageBox::Critical, "Error", "Open file error", QMessageBox::Ok); } } else { event->ignore(); } }
QTextDocument是表示文本及文本屬性的數據類。能夠設置文本屬性如:排版、字體、標題;獲取文本參數如:行數、文本寬度、文本信息;實現標準操做如:撤銷、重作、查找、打印。
打印功能實現以下:
A、鏈接打印功能的QAction對象到打印功能槽函數
B、在打印槽函數中定義打印對話框
C、根據用戶選擇獲取QPrinter對象
D、使用QTextDocument對象進行打印
void MainWindow::onPrint() { QPrintDialog printdialog(this); printdialog.setWindowTitle("Print"); if(printdialog.exec() == QPrintDialog::Accepted) { QPrinter *printer = printdialog.printer(); mainEditor.document()->print(printer); } }
QPlainTextEdit編輯框內部包含QTextCursor對象。
[signal] void QPlainTextEdit::cursorPositionChanged()
QTextCursor QPlainTextEdit::textCursor() const
int QTextCursor::position() const
void MainWindow::onCursorChanged() { int pos = mainEditor.textCursor().position(); QString text = mainEditor.toPlainText(); int colum = 0; int row = 0; int flag = -1; for(int i = 0; i < pos; i++) { if( text[i] == '\n' ) { row++; flag = i; } } flag++; colum = pos - flag; m_status.setText("Line: " + QString::number(row + 1) + " Colum: " + QString::number(colum + 1)); }
1)查找對話框的功能:
A、可複用的組件
B、查找文本框中的指定字符串
C、可以指定查找方向
D、支持大小寫敏感查找
(2)查找對話框架構設計以下:
(3)查找對話框的界面佈局:
4)查找功能的實現:
A、獲取當前光標的位置做爲起始點
B、查找目標第一次出現的位置
C、經過目標位置和目標長度在文本框內進行標記
QString類提供了字符串中查找子串的函數:
int QString::indexOf(const QString &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
從指定位置向後查找子串的下標位置
int QString::lastIndexOf(const QString &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
從指定位置向前查找子串的下標位置
QPlainTextEdit文本框中選中子串的標記
QTextCursor cursor = m_textedit->textCursor();//獲取當前光標
cursor.setPosition(index);//設置光標到下標index
cursor.setPosition(index + target.length(), QTextCursor::KeepAnchor);//設置文本選擇範圍
m_textedit->setTextCursor(cursor);//設置光標信息到文本
(5)FindDailog類與MainWindow類的弱耦合關係
經過setPlainTextEdit(pText)設置FindDailog查找對話框指向的文本框,確立了FindDailog類與MainWindow類的弱耦合關係。
//設置mainEditor的背景色爲豆沙綠
QPalette p = mainEditor.palette();
p.setColor(QPalette::Base, QColor(204, 232, 207));
p.setColor(QPalette::Inactive, QPalette::Highlight, p.color(QPalette::Active, QPalette::Highlight));
p.setColor(QPalette::Inactive, QPalette::HighlightedText, p.color(QPalette::Active, QPalette::HighlightedText));
mainEditor.setPalette(p);
替換對話框的功能:
A、可複用的組件
B、查找文本框中的字符串
C、替換當前查找到的字符串
D、替換全部的字符串
E、點擊關閉按鈕後隱藏
替換對話框的架構設計:
考慮到FindDialog類代碼複用,RepalceDialog類繼承自FindDialog。
替換對話框界面設計:
m_replacelabel.setText("Replace To:"); m_replacebutton.setText("Replace"); m_replaceallbutton.setText("Replace All"); m_layout.removeWidget(&m_check); m_layout.removeWidget(&m_radiogroup); m_layout.removeWidget(&m_cancelbutton); m_layout.addWidget(&m_replacelabel, 1, 0); m_layout.addWidget(&m_replaceedit, 1, 1); m_layout.addWidget(&m_replacebutton, 1, 2); m_layout.addWidget(&m_check, 2, 0); m_layout.addWidget(&m_radiogroup, 2, 1); m_layout.addWidget(&m_replaceallbutton, 2, 2); m_layout.addWidget(&m_cancelbutton, 3, 2);
替換功能的實現:
要實現替換操做,首先須要查找文本框中是否存在的字符串。若是存在字符串,則將鼠標標記的字符串替換。
void ReplaceDialog::onReplace() { QString target = m_edit.text(); QString to = m_replaceedit.text(); if((m_textedit != NULL) && (target != NULL) && (to != NULL)) { QString select = m_textedit->textCursor().selectedText(); if(select == target) { m_textedit->insertPlainText(to); } onFind(); } } void ReplaceDialog::onRepalceAll() { QString target = m_edit.text(); QString to = m_replaceedit.text(); if((m_textedit != NULL) && (target != NULL) && (to != NULL)) { QString text = m_textedit->toPlainText(); text.replace(target, to, m_check.isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive); m_textedit->clear(); m_textedit->insertPlainText(text); } }
在構建菜單欄、工具欄中ToolBar、StatusBar的QAction對象時,設置QAction對象的屬性。
action->setCheckable(true);
action->setChecked(true);
connect(action, SIGNAL(triggered()), this, SLOT(onViewToolBar()));
槽函數以下:
void MainWindow::onViewStatusBar() { QStatusBar *sb = statusBar(); bool visible = sb->isVisible(); sb->setVisible(!visible); findToolBarItem("Status Bar")->setChecked(!visible); findMenuBarItem("Status Bar")->setChecked(!visible); } void MainWindow::onViewToolBar() { const QObjectList& list = children(); for(int i = 0; i < list.count(); i++) { QToolBar *tb = dynamic_cast<QToolBar*>(list[i]); if(tb != NULL) { bool visible = tb->isVisible(); tb->setVisible(!visible); findMenuBarItem("Tool Bar")->setChecked(!visible); findToolBarItem("Tool Bar")->setChecked(!visible); break; } } }
關於對話框用於標識軟件的信息,如:Logo、版本號、開發者信息、版權、聯繫方式、項目信息等。
經典的關於對話框界面設計:
AboutDialog::AboutDialog(QWidget* parent) :QDialog(parent, Qt::WindowCloseButtonHint), m_logo(this), m_info(this), m_close(this) { QPixmap pm(":/res/pic/dt.png"); pm = pm.scaled(120,120, Qt::KeepAspectRatio); m_logo.setPixmap(pm); m_logo.move(20, 20); m_logo.resize(120, 120); QPalette p = m_info.palette(); p.setColor(QPalette::Active, QPalette::Base, palette().color(QPalette::Active, QPalette::Background)); p.setColor(QPalette::Inactive, QPalette::Base, palette().color(QPalette::Inactive, QPalette::Background)); m_info.setPalette(p); m_info.move(200, 30); m_info.resize(180, 130); m_info.setFrameStyle(QPlainTextEdit::NoFrame); m_info.setReadOnly(true); m_info.insertPlainText("NotePad Project\n\nPlatform: Qt 5.6.2\n\nVersion: 1.0.0\n\nAuthor: Scorpio"); m_close.setText("Close"); m_close.move(273, 175); m_close.resize(100, 30); setWindowTitle("About NotePad"); setFixedSize(395, 230); connect(&m_close, SIGNAL(clicked()), this, SLOT(onClose())); }
設置文本框中的字體的屬性。
字體設置經過QFontDialog對話框實現
槽函數以下:
void MainWindow::onFormatFont() { bool ok = false; QFont font = QFontDialog::getFont(&ok, mainEditor.font(), this); if(ok) { mainEditor.setFont(font); } }
QPlainTextEdit支持換行操做。在菜單欄、工具欄建立QAction對象時設置屬性。
action->setCheckable(true);
action->setChecked(true);
connect(action, SIGNAL(triggered()), this, SLOT(onFormatWrap()));
槽函數以下:
void MainWindow::onFormatWrap() { QPlainTextEdit::LineWrapMode mode = mainEditor.lineWrapMode(); if(mode == QPlainTextEdit::NoWrap) { mainEditor.setLineWrapMode(QPlainTextEdit::WidgetWidth); findMenuBarItem("Auto Wrap")->setChecked(true); findToolBarItem("Auto Wrap")->setChecked(true); } else { mainEditor.setLineWrapMode(QPlainTextEdit::NoWrap); findMenuBarItem("Auto Wrap")->setChecked(false); findToolBarItem("Auto Wrap")->setChecked(false); } }
QDesktopServices提供了一系列桌面開發的服務接口。
經過QDesktopServices的成員函數打開幫助文檔。
[static] bool QDesktopServices::openUrl(const QUrl &url)
打開網頁:
QDesktopServices::openUrl(QUrl("http://9291927.blog.51cto.com/"));
打開文檔:
QDesktopServices::openUrl(QUrl("file:///C:/Documents and Settings/All Users/Desktop/help.pdf"));
程序狀態的保存能夠經過在程序退出前保存程序狀態參數到文件(數據庫),程序啓動時從配置文件讀出狀態參數並恢復。
程序狀態參數的存儲方式:
A、文本文件格式(XML、Json等)
B、輕量級數據庫(Access、SQLite等)
C、二進制文件格式
經過二進制數據流將狀態參數直接存儲帶文件中。
Appconfig.h文件:
#ifndef APPCONFIG_H #define APPCONFIG_H #include <QObject> #include <QFont> #include <QFile> #include <QDataStream> #include <QApplication> class AppConfig : public QObject { Q_OBJECT public: explicit AppConfig(QObject *parent = 0); explicit AppConfig(QFont editorfont, bool isautowrap, bool istoolbarvisible, bool isstatusbarvisible, QObject *parent = 0); bool store(); QFont editorFont(); bool isAutoWrap(); bool isToolBarVisible(); bool isStatusBarVisible(); bool isValid(); private: bool restore(); private: QFont m_editorFont; bool m_isAutoWrap; bool m_isToolBarVisible; bool m_isStatusBarVisible; bool m_isValid; }; #endif // APPCONFIG_H
Appconfig.cpp文件:
#include "AppConfig.h" AppConfig::AppConfig(QObject *parent) : QObject(parent) { m_isValid = restore(); } AppConfig::AppConfig(QFont editorfont, bool isautowrap, bool istoolbarvisible, bool isstatusbarvisible, QObject *parent) { m_editorFont = editorfont; m_isAutoWrap = isautowrap; m_isToolBarVisible = istoolbarvisible; m_isStatusBarVisible = isstatusbarvisible; m_isValid = true; } QFont AppConfig::editorFont() { return m_editorFont; } bool AppConfig::isAutoWrap() { return m_isAutoWrap; } bool AppConfig::isStatusBarVisible() { return m_isStatusBarVisible; } bool AppConfig::isToolBarVisible() { return m_isToolBarVisible; } bool AppConfig::isValid() { return m_isValid; } bool AppConfig::store() { bool ret = true; QFile file(QApplication::applicationDirPath() + "/config.dat"); if(file.open(QIODevice::WriteOnly)) { QDataStream out(&file); out.setVersion(QDataStream::Qt_5_6); out << m_editorFont; out << m_isAutoWrap; out << m_isToolBarVisible; out << m_isStatusBarVisible; file.close(); } else { ret = false; } return ret; } bool AppConfig::restore() { bool ret = true; QFile file(QApplication::applicationDirPath() + "/config.dat"); if(file.open(QIODevice::ReadOnly)) { QDataStream in(&file); in.setVersion(QDataStream::Qt_5_6); in >> m_editorFont; in >> m_isAutoWrap; in >> m_isToolBarVisible; in >> m_isStatusBarVisible; file.close(); } else { ret = false; } return ret; }
從配置文件的讀取狀態參數恢復程序狀態在構造函數中:
bool MainWindow::construct() { bool ret = true; AppConfig config; ret = ret && initMenuBar(); ret = ret && initToolBar(); ret = ret && initStatusBar(); ret = ret && initMainEditor(); if(config.isValid()) { mainEditor.setFont(config.editorFont()); if(!config.isAutoWrap()) { mainEditor.setLineWrapMode(QPlainTextEdit::NoWrap); findToolBarItem("Auto Wrap")->setCheckable(false); findMenuBarItem("Auto Wrap")->setChecked(false); } if(!config.isToolBarVisible()) { toolBar()->setVisible(false); findMenuBarItem("Tool Bar")->setChecked(false); findToolBarItem("Tool Bar")->setChecked(false); } if(!config.isStatusBarVisible()) { statusBar()->setVisible(false); findMenuBarItem("Status Bar")->setChecked(false); findToolBarItem("Status Bar")->setChecked(false); } } return ret; }
狀態參數保存到配置文件在析構函數中:
MainWindow::~MainWindow() { QFont font = mainEditor.font(); bool isautowrap = (mainEditor.lineWrapMode() == QPlainTextEdit::WidgetWidth); bool istoolbarvisible = (findMenuBarItem("Tool Bar")->isChecked() && findToolBarItem("Tool Bar")->isChecked()); bool isstatusbarvisible = (findMenuBarItem("Status Bar")->isChecked() && findToolBarItem("Status Bar")->isChecked()); AppConfig config(font, isautowrap, istoolbarvisible, isstatusbarvisible); config.store(); }
開發環境QT 5.6
源碼見附件:NotePad.zip