赞
踩
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。
- QMenuBar* mb = menuBar();
-
- QMenu* menu = new QMenu("File(&F)");
-
- QAction *action = new QAction(text, NULL);
-
- 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();
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。