1 环境:
系统:windows 10
代码编写运行环境:Qt Creator 4.4.1 (community)
GitHub:https://github.com/zhengcixi/mynotepad
2 参考代码
Karllen:qt5.5实现 记事本程序 https://www.cnblogs.com/Forever-Kenlen-Ja/p/4985133.html
3 实现效果
主界面如下:
下面依次演示操作各个菜单:
(1)文件菜单
包括:新建、新窗口、打开、保存、另存为、打印、退出等功能。
(2)编辑菜单
包括:撤销、剪切、复制、粘贴、删除、查找、替换、全选等功能。
全部替换的功能还存在bug。
(3)格式菜单
包括:更换字体,自动换行功能。
自动换行功能还没有实现。
(4)查看菜单
实现功能:放大、缩小以及状态栏的查看。
放大和缩小功能使用的是QTextEdit自带的槽函数处理,但是没有效果,不知道为什么。
状态栏功能没有实现,现在状态栏默认是打开的,显示的是文本中的鼠标所在的字符是第几个字符。
(5)帮助菜单栏
实现功能:帮助菜单和关于记事本。
点击帮助菜单,会弹出一个网页并跳转到本博客。
点击关于记事本,会弹出一个消息框。
至此,记事本实现的功能就大致如此了,上述的功能大部分也可以通过快捷键的方式进行访问。
下面简单说说工程的组织结构,及部分代码。
4 工程结构及代码说明
工程包含的文件有:
其中,mainwindow.h和mainwindow.cpp是主窗口的相关文件,finddialog.h和finddialog.cpp是查找对话框的相关文件,replacedialog.h和replacedialog.cpp是替换对话框的相关文件。
先给出各个文件的源代码:
finddialog.h

1 #ifndef FINDDIALOG_H 2 #define FINDDIALOG_H 3 4 #include5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 #include 14 #include 15 16 class FindDialog : public QDialog 17 { 18 Q_OBJECT 19 public: 20 explicit FindDialog(QWidget *parent = nullptr); 21 22 signals: 23 //参数:查找关键字、是否区分大小写、向前或向后查找 24 void findTextDataButtonClickedSignal(QString, bool, bool); 25 26 public slots: 27 void findButtonState(); 28 void findDataButtonClickedState(); 29 30 private: 31 QLineEdit *find_edit; 32 QLabel *find_label, *ignore_label, *next_label, *back_label; 33 QPushButton *find_button; 34 QRadioButton *next_radio; 35 QRadioButton *back_radio; 36 QCheckBox *ignore_flag; 37 }; 38 39 #endif // FINDDIALOG_H
mainwindow.h

1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #include5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 #include 14 #include 15 #include 16 #include "finddialog.h" 17 #include "replacedialog.h" 18 19 class MainWindow : public QMainWindow 20 { 21 Q_OBJECT 22 23 public: 24 MainWindow(QWidget *parent = 0); 25 ~MainWindow(); 26 //常用函数 27 void CreateMenu(); //创建主菜单 28 void Creatslots(); //创建各组件的槽函数 29 void save_file(); //保存文件 30 31 /* 槽函数 */ 32 //菜单项--文件相关功能:新建、新建新窗口、打卡、保存、另存、打印、退出 33 void slot_menu_file_new(void); 34 void slot_menu_file_new_win(void); 35 void slot_menu_file_open(void); 36 void slot_menu_file_save(void); 37 void slot_menu_file_save_as(void); 38 void slot_menu_file_print(void); 39 void slot_menu_file_quit(void); 40 41 //菜单项--编辑相关功能:撤销、剪切、复制、粘贴、删除、查找、替换、全选 42 void slot_menu_edit_undo(void); 43 void slot_menu_edit_cut(void); 44 void slot_menu_edit_copy(void); 45 void slot_menu_edit_paste(void); 46 void slot_menu_edit_delete(void); 47 void slot_menu_edit_find(); 48 void slot_menu_edit_replace(void); 49 void slot_menu_edit_all(void); 50 51 //菜单项--格式相关功能:自动换行、格式 52 void slot_menu_format_warp(void); 53 void slot_menu_format_font(void); 54 55 //菜单项--查看相关功能:放大、缩小、状态栏 56 void slot_menu_view_zoon_in(void); 57 void slot_menu_view_zoon_out(void); 58 void slot_menu_view_status(void); 59 60 //菜单项--帮助相关功能:查看帮助、关于 61 void slot_menu_help_view(void); 62 void slot_menu_help_about(void); 63 64 //查找、替换 65 void findAct(QString, bool, bool); 66 void findReplace(QString, bool); 67 void replaceCur(QString, QString); 68 void replaceAll(QString, QString, bool); 69 70 //文本状态发生变化时调用 71 void slot_judge_text_state(); 72 //文本中的鼠标发生状态时调用 73 void slot_cursor_change_state(); 74 75 private: 76 QTextEdit *textEdit; 77 QString cur_file_name; 78 QString sbar_str; //状态栏 79 80 /* 添加菜单栏 */ 81 QMenuBar *qBar; 82 //菜单--文件 83 QMenu *menu_file; 84 QAction *menu_file_new; 85 QAction *menu_file_new_win; 86 QAction *menu_file_open; 87 QAction *menu_file_save; 88 QAction *menu_file_save_as; 89 QAction *menu_file_print; 90 QAction *menu_file_quit; 91 92 //菜单--编辑 93 QMenu *menu_edit; 94 QAction *menu_edit_undo; 95 QAction *menu_edit_cut; 96 QAction *menu_edit_copy; 97 QAction *menu_edit_paste; 98 QAction *menu_edit_delete; 99 QAction *menu_edit_find; 100 QAction *menu_edit_replace; 101 QAction *menu_edit_all; 102 103 //菜单--格式 104 QMenu *menu_format; 105 QAction *menu_format_warp; 106 QAction *menu_format_font; 107 108 //菜单--查看 109 QMenu *menu_view; 110 QAction *menu_view_zoom_in; 111 QAction *menu_view_zoom_out; 112 QAction *menu_view_status; 113 114 //菜单--帮助 115 QMenu *menu_help; 116 QAction *menu_help_view; 117 QAction *menu_help_about; 118 119 /* 添加状态栏 */ 120 QStatusBar *sbar; 121 QLabel *label; 122 123 /* 查找替换 */ 124 bool find; 125 FindDialog *find_dialog; 126 replacedialog *replace_dialog; 127 128 /* 剪贴板 */ 129 QClipboard *clipboard; 130 }; 131 132 #endif // MAINWINDOW_H
replacedialog.h

1 #ifndef REPLACEDIALOG_H 2 #define REPLACEDIALOG_H 3 4 #include5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 14 class replacedialog : public QDialog 15 { 16 Q_OBJECT 17 public: 18 explicit replacedialog(QWidget *parent = nullptr); 19 20 signals: 21 void signal_replaceAllStr(QString, QString, bool); 22 void signal_replaceCurOneStr(QString, QString); 23 void signal_findReplaceStr(QString, bool); 24 25 public slots: 26 void slot_choose_str(); 27 void slot_find_button_state(); 28 void slot_replace_one_button_state(); 29 void slot_repalce_all_button_state(); 30 31 private: 32 QLineEdit *find_str; 33 QLineEdit *replace_str; 34 QPushButton *find_next_button; 35 QPushButton *replace_one_button; 36 QPushButton *replace_all_button; 37 QPushButton *cancel_button; 38 QCheckBox *ignore_flag; 39 QLabel *find_label; 40 QLabel *replace_label; 41 42 }; 43 44 #endif // REPLACEDIALOG_H
finddialog.cpp

1 #include "finddialog.h" 2 #include3 4 FindDialog::FindDialog(QWidget *parent) : QDialog(parent) 5 { 6 setWindowTitle("查找"); 7 find_label = new QLabel("查找"); 8 ignore_label= new QLabel("区分大小写"); 9 next_label = new QLabel("向后"); 10 back_label = new QLabel("向前"); 11 find_edit = new QLineEdit; 12 find_button = new QPushButton("查找下一个"); 13 next_radio = new QRadioButton; 14 back_radio = new QRadioButton; 15 ignore_flag = new QCheckBox; 16 17 find_edit->setText(""); 18 19 QGridLayout *grid_layout = new QGridLayout(this); 20 grid_layout->addWidget(find_label, 0, 0); 21 grid_layout->addWidget(find_edit, 0, 1); 22 grid_layout->addWidget(find_button, 0, 3); 23 24 QHBoxLayout *ignore_layout = new QHBoxLayout; 25 ignore_layout->setSpacing(10); 26 ignore_layout->addWidget(ignore_label); 27 ignore_layout->addWidget(ignore_flag); 28 29 QHBoxLayout *radio_layout = new QHBoxLayout; 30 radio_layout->addWidget(next_label); 31 radio_layout->addWidget(next_radio); 32 radio_layout->addWidget(back_label); 33 radio_layout->addWidget(back_radio); 34 35 QGroupBox *group_radio = new QGroupBox("方向", this); 36 group_radio->setLayout(radio_layout); 37 38 QHBoxLayout *do_radio = new QHBoxLayout; 39 do_radio->addWidget(group_radio); 40 41 grid_layout->addLayout(ignore_layout, 1, 0); 42 grid_layout->addLayout(do_radio, 1, 1); 43 44 this->setMaximumSize(400, 200); 45 this->setMinimumSize(350, 150); 46 next_radio->setCheckable(true); 47 find_button->setEnabled(false); 48 connect(find_edit, &QLineEdit::textChanged, this, &FindDialog::findButtonState); 49 connect(find_button, &QPushButton::clicked, this, &FindDialog::findDataButtonClickedState); 50 } 51 52 void FindDialog::findButtonState() 53 { 54 if (find_edit->text().isEmpty()) { 55 find_button->setEnabled(false); 56 } else { 57 find_button->setEnabled(true); 58 } 59 } 60 void FindDialog::findDataButtonClickedState() 61 { 62 if (find_edit->text().isEmpty()) { 63 return; 64 } 65 QString str = find_edit->text(); 66 if (next_radio->isChecked()) { 67 if (ignore_flag->isChecked()) { 68 emit findTextDataButtonClickedSignal(str, true, true); 69 } else { 70 emit findTextDataButtonClickedSignal(str, false, true); 71 } 72 } 73 if (back_radio->isChecked()) { 74 if (ignore_flag->isChecked()) { 75 emit findTextDataButtonClickedSignal(str, true, false); 76 } else { 77 emit findTextDataButtonClickedSignal(str, false, false); 78 } 79 } 80 }
main.cpp

1 #include "mainwindow.h" 2 #include3 4 int main(int argc, char *argv[]) 5 { 6 QApplication a(argc, argv); 7 MainWindow w; 8 w.show(); 9 10 return a.exec(); 11 }
mainwindow.cpp

1 #include "mainwindow.h" 2 #include3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 #include 14 #include 15 #include 16 #include 17 #include 18 #include 19 #include 20 21 MainWindow::MainWindow(QWidget *parent) 22 : QMainWindow(parent) 23 { 24 //查找文本框 25 find_dialog = new FindDialog(this); 26 //替换文本框 27 replace_dialog = new replacedialog(this); 28 //剪贴板 29 clipboard = QApplication::clipboard(); 30 31 this->resize(900, 700); 32 CreateMenu(); 33 Creatslots(); 34 } 35 36 void MainWindow::CreateMenu() 37 { 38 /* 添加核心控件 */ 39 textEdit = new QTextEdit(this); 40 this->setCentralWidget(textEdit); 41 cur_file_name = ""; 42 sbar = statusBar(); 43 label = new QLabel(this); 44 45 /* 添加菜单栏 */ 46 qBar = menuBar(); 47 //添加菜单--文件 48 menu_file = qBar->addMenu("文件(F)"); 49 menu_file_new = menu_file->addAction("新建(N)"); 50 menu_file_new->setShortcut(QKeySequence::New); 51 menu_file_new_win = menu_file->addAction("新窗口(W)"); 52 menu_file_open = menu_file->addAction("打开(O)"); 53 menu_file_open->setShortcut(QKeySequence::Open); 54 menu_file_save = menu_file->addAction("保存(S)"); 55 menu_file_save->setShortcut(QKeySequence::Save); 56 menu_file_save_as = menu_file->addAction("另存为(S)"); 57 menu_file_save_as->setShortcut(QKeySequence::SaveAs); 58 menu_file->addSeparator(); 59 menu_file_print = menu_file->addAction("打印(P)"); 60 menu_file_print->setShortcut(QKeySequence::Print); 61 menu_file->addSeparator(); 62 menu_file_quit = menu_file->addAction("退出(X)"); 63 menu_file_quit->setShortcut(QKeySequence::Quit); 64 65 //添加菜单项--编辑 66 menu_edit = qBar->addMenu("编辑(E)"); 67 menu_edit_undo = menu_edit->addAction("撤销(U)"); 68 menu_edit_undo->setShortcut(QKeySequence::Undo); 69 menu_edit_undo->setEnabled(false); 70 menu_edit->addSeparator(); 71 menu_edit_cut = menu_edit->addAction("剪切(T)"); 72 menu_edit_cut->setShortcut(QKeySequence::Cut); 73 menu_edit_cut->setEnabled(false); 74 menu_edit_copy = menu_edit->addAction("复制(C)"); 75 menu_edit_copy->setShortcut(QKeySequence::Copy); 76 menu_edit_copy->setEnabled(false); 77 menu_edit_paste = menu_edit->addAction("粘贴(P)"); 78 menu_edit_paste->setShortcut(QKeySequence::Paste); 79 menu_edit_delete = menu_edit->addAction("删除(D)"); 80 menu_edit_delete->setShortcut(QKeySequence::Delete); 81 menu_edit_delete->setEnabled(false); 82 menu_edit_delete->setShortcut(QKeySequence::Delete); 83 menu_edit->addSeparator(); 84 menu_edit_find = menu_edit->addAction("查找(F)"); 85 menu_edit_find->setShortcut(QKeySequence::Find); 86 menu_edit_replace = menu_edit->addAction("替换(R)"); 87 menu_edit_replace->setShortcut(QKeySequence::Replace); 88 menu_edit->addSeparator(); 89 menu_edit_all = menu_edit->addAction("全选(A)"); 90 menu_edit_all->setShortcut(QKeySequence::SelectAll); 91 92 //添加菜单项--格式 93 menu_format = qBar->addMenu("格式(O)"); 94 menu_format_warp = menu_format->addAction("自动换行(W)"); 95 menu_format_font = menu_format->addAction("字体(F)"); 96 97 //添加菜单项--查看 98 menu_view = qBar->addMenu("查看(V)"); 99 menu_view_zoom_in = menu_view->addAction("放大(Z)"); 100 menu_view_zoom_in->setShortcut(QKeySequence::ZoomIn); 101 menu_view_zoom_out = menu_view->addAction("缩小(Z)"); 102 menu_view_zoom_out->setShortcut(QKeySequence::ZoomOut); 103 menu_view_status = menu_view->addAction("状态栏(S)"); 104 105 //添加菜单项--帮助 106 menu_help = qBar->addMenu("帮助(H)"); 107 menu_help_view = menu_help->addAction("查看帮助(H)"); 108 menu_help_about = menu_help->addAction("关于记事本(A)"); 109 } 110 111 void MainWindow::Creatslots() 112 { 113 //菜单 -- 文件 114 connect(menu_file_new, &QAction::triggered, this, &MainWindow::slot_menu_file_new); 115 connect(menu_file_new_win, &QAction::triggered, this, &MainWindow::slot_menu_file_new_win); 116 connect(menu_file_open, &QAction::triggered, this, &MainWindow::slot_menu_file_open); 117 connect(menu_file_save, &QAction::triggered, this, &MainWindow::slot_menu_file_save); 118 connect(menu_file_save_as, &QAction::triggered, this, &MainWindow::slot_menu_file_save_as); 119 connect(menu_file_print, &QAction::triggered, this, &MainWindow::slot_menu_file_print); 120 connect(menu_file_quit, &QAction::triggered, this, &MainWindow::slot_menu_file_quit); 121 122 //菜单 -- 编辑 123 connect(menu_edit_delete, &QAction::triggered, this, &MainWindow::slot_menu_edit_delete); 124 connect(menu_edit_undo, &QAction::triggered, textEdit, &textEdit->undo); //使用QTextEdit自带的槽函数 125 connect(menu_edit_cut, &QAction::triggered, textEdit, &textEdit->cut); 126 connect(menu_edit_copy, &QAction::triggered, textEdit, &textEdit->copy); 127 connect(menu_edit_paste, &QAction::triggered, textEdit, &textEdit->paste); 128 connect(menu_edit_find, &QAction::triggered, this, &MainWindow::slot_menu_edit_find); 129 connect(menu_edit_replace, &QAction::triggered, this, &MainWindow::slot_menu_edit_replace); 130 connect(menu_edit_all, &QAction::triggered, textEdit, &textEdit->selectAll); 131 132 //菜单 -- 格式 133 connect(menu_format_warp, &QAction::triggered, this, &MainWindow::slot_menu_format_warp); 134 connect(menu_format_font, &QAction::triggered, this, &MainWindow::slot_menu_format_font); 135 136 //菜单 -- 查看 137 connect(menu_view_zoom_in, &QAction::triggered, textEdit, &textEdit->zoomIn); 138 connect(menu_view_zoom_out,&QAction::triggered, textEdit, &textEdit->zoomOut); 139 connect(menu_view_status, &QAction::triggered, this, &MainWindow::slot_menu_view_status); 140 141 //菜单 -- 帮助 142 connect(menu_help_view, &QAction::triggered, this, &MainWindow::slot_menu_help_view); 143 connect(menu_help_about, &QAction::triggered, this, &MainWindow::slot_menu_help_about); 144 145 //查找、替换 146 connect(find_dialog, &FindDialog::findTextDataButtonClickedSignal, this, &MainWindow::findAct); 147 connect(replace_dialog, &replacedialog::signal_findReplaceStr, this, &MainWindow::findReplace); 148 connect(replace_dialog, &replacedialog::signal_replaceCurOneStr, this, &MainWindow::replaceCur); 149 connect(replace_dialog, &replacedialog::signal_replaceAllStr, this, &MainWindow::replaceAll); 150 151 //判断文本框是否已经改变 152 connect(textEdit, &QTextEdit::textChanged, this, &MainWindow::slot_judge_text_state); 153 connect(textEdit, &QTextEdit::cursorPositionChanged, this, &MainWindow::slot_cursor_change_state); 154 } 155 156 //菜单项--文件 157 void MainWindow::slot_menu_file_new(void) 158 { 159 /* 160 * 1、如果文本框是空白的,就直接新建; 161 * 2、如果文本框有内容,但内容未修改,则直接新建; 162 * 3、如果文本框有内容,且内容被修改过,则询问是否保存。 163 */ 164 if (textEdit->document()->isModified()) { 165 QMessageBox::StandardButton button = QMessageBox::information(this, 166 "未保存", "是否保存?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); 167 switch (button) { 168 case QMessageBox::Save: 169 save_file(); 170 if (textEdit->document()->isModified()) { 171 return; 172 } 173 break; 174 case QMessageBox::Cancel: 175 return; 176 case QMessageBox::Discard: 177 break; 178 default: 179 break; 180 } 181 } 182 textEdit->clear(); 183 } 184 void MainWindow::slot_menu_file_new_win(void) 185 { 186 MainWindow *new_win = new MainWindow(); 187 new_win->show(); 188 } 189 void MainWindow::slot_menu_file_open(void) 190 { 191 /* 192 * 1、如果文本框是空的,则直接打开文件; 193 * 2、如果文本框有内容,且内容被修改过,则询问是否保存,再打开文件。 194 */ 195 if (textEdit->document()->isModified()) 196 { 197 QMessageBox::StandardButton button = QMessageBox::information(this, 198 "未保存", "是否保存?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); 199 switch (button) { 200 case QMessageBox::Save: 201 save_file(); 202 if (textEdit->document()->isModified()) { 203 return; 204 } 205 break; 206 case QMessageBox::Cancel: 207 return; 208 case QMessageBox::Discard: 209 break; 210 default: 211 break; 212 } 213 } 214 215 QString file_name = QFileDialog::getOpenFileName(this, "open file", "../", "文本文档(*.txt);;所有文件(*.*)"); 216 cur_file_name = file_name; 217 if (!file_name.isEmpty()) { 218 QFile file(file_name); 219 if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) { 220 QMessageBox::critical(this, "错误", "不能打开文件"); 221 return; 222 } 223 QTextStream ins(&file); 224 textEdit->setText(ins.readAll()); 225 file.close(); 226 } 227 } 228 void MainWindow::slot_menu_file_save(void) 229 { 230 /* 231 * 1、如果文本框是空的,则直接返回; 232 * 2、如果文本框中存在内容,且没有在一个文件中,则询问是否新建个文件保存; 233 * 3、如果文本框中存在内容,且已经在一个文件中,则将内容保存进文件。 234 */ 235 if (textEdit->toPlainText().isEmpty()) { 236 return; 237 } 238 239 if (cur_file_name.isEmpty()) { 240 QString file_name =QFileDialog::getSaveFileName(this, "保存文件", "../", "文本文档(*.txt);;所有文件(*.*)"); 241 if (!file_name.isEmpty()) { 242 QFile file(file_name); 243 if (!file.open(QIODevice::WriteOnly)) { 244 QMessageBox::critical(this, "错误", "不能打开文件"); 245 return; 246 } 247 QTextStream outs(&file); 248 outs< toPlainText(); 249 outs.flush(); 250 file.close(); 251 } 252 } else { 253 QFile file(cur_file_name); 254 if (!file.open(QIODevice::WriteOnly)) { 255 QMessageBox::critical(this, "错误", "不能打开文件"); 256 return; 257 } 258 QTextStream outs(&file); 259 outs< toPlainText(); 260 outs.flush(); 261 file.close(); 262 } 263 } 264 void MainWindow::slot_menu_file_save_as(void) 265 { 266 /* 267 * 1、如果文本框是空的,则直接返回; 268 * 2、如果文本框中存在内容,则询问是否保存。 269 */ 270 if (textEdit->toPlainText().isEmpty()) { 271 return; 272 } 273 QString file_name =QFileDialog::getSaveFileName(this, "保存文件", "../", "文本文档(*.txt);;所有文件(*.*)"); 274 if (!file_name.isEmpty()) { 275 QFile file(file_name); 276 if (!file.open(QIODevice::WriteOnly)) { 277 QMessageBox::critical(this, "错误", "不能打开文件"); 278 return; 279 } 280 QTextStream outs(&file); 281 outs << textEdit->toPlainText(); 282 outs.flush(); 283 file.close(); 284 } 285 } 286 void MainWindow::slot_menu_file_print(void) 287 { 288 if (textEdit->toPlainText().isEmpty()) { 289 return; 290 } 291 QPrinter printer; 292 QString printer_name = printer.printerName(); 293 QPrintDialog print_dlg(&printer, this); 294 if (printer_name.size() == 0) { 295 return; 296 } 297 if (textEdit->textCursor().hasSelection()) { 298 print_dlg.addEnabledOption(QAbstractPrintDialog::PrintSelection); 299 } 300 if (print_dlg.exec() == QDialog::Accepted) { 301 textEdit->print(&printer); 302 } 303 } 304 void MainWindow::slot_menu_file_quit(void) 305 { 306 this->close(); 307 } 308 309 //菜单项--编辑 310 void MainWindow::slot_menu_edit_delete(void) 311 { 312 textEdit->cut(); 313 clipboard->setText(""); 314 } 315 void MainWindow::slot_menu_edit_replace(void) 316 { 317 replace_dialog->show(); 318 } 319 void MainWindow::slot_menu_edit_find(void) 320 { 321 find_dialog->show(); 322 } 323 324 //菜单项--格式 325 void MainWindow::slot_menu_format_warp(void) 326 { 327 328 } 329 void MainWindow::slot_menu_format_font(void) 330 { 331 QFontDialog font_dialog; 332 font_dialog.show(); 333 QFont inifont = textEdit->font(); 334 bool ok = false; 335 QFont font = font_dialog.getFont(&ok, inifont); 336 if (ok) { 337 textEdit->setFont(font); 338 } 339 font_dialog.close(); 340 } 341 342 //菜单项--查看 343 void MainWindow::slot_menu_view_status(void) 344 { 345 346 } 347 348 //菜单项--帮助 349 void MainWindow::slot_menu_help_view(void) 350 { 351 QDesktopServices::openUrl(QUrl(QLatin1String("https://www.cnblogs.com/mrlayfolk/p/13167219.html"))); 352 } 353 void MainWindow::slot_menu_help_about(void) 354 { 355 QMessageBox message(QMessageBox::NoIcon, "关于", ("version: v1.0\nauthor: zzq\nqq: 544705365")); 356 message.exec(); 357 } 358 359 360 //保存文件 361 void MainWindow::save_file() 362 { 363 if (cur_file_name.isEmpty()) { 364 QString file_name =QFileDialog::getSaveFileName(this, "保存文件", "../", "文本文档(*.txt);;所有文件(*.*)"); 365 if (!file_name.isEmpty()) { 366 QFile file(file_name); 367 if (!file.open(QIODevice::WriteOnly)) { 368 QMessageBox::critical(this, "错误", "不能打开文件"); 369 return; 370 } 371 QTextStream outs(&file); 372 outs.setCodec("utf-8"); 373 outs< toPlainText(); 374 outs.flush(); 375 file.close(); 376 textEdit->document()->setModified(false); 377 } 378 } else { 379 QFile file(cur_file_name); 380 if (!file.open(QIODevice::WriteOnly)) { 381 QMessageBox::critical(this, "错误", "不能打开文件"); 382 return; 383 } 384 QTextStream outs(&file); 385 outs.setCodec("utf-8"); 386 outs< toPlainText(); 387 outs.flush(); 388 file.close(); 389 textEdit->document()->setModified(false); 390 } 391 } 392 393 //查找 394 void MainWindow::findAct(QString str_key, bool ignore_case, bool choose_direction) 395 { 396 /* 397 * 参数str_key:查找的关键字,支持中文 398 * 参数ignore_case:是否区分大小写 399 * 参数choose_direction:向前或向后查找,true:向前;false:先后; 400 */ 401 bool find_flag; 402 if (!str_key.isEmpty()) { 403 if (choose_direction) { 404 if (ignore_case) { 405 find_flag = textEdit->find(str_key, QTextDocument::FindCaseSensitively); 406 } else { 407 find_flag = textEdit->find(str_key); 408 } 409 } else { 410 if (ignore_case) { 411 find_flag = textEdit->find(str_key, QTextDocument::FindBackward|QTextDocument::FindCaseSensitively); 412 } else { 413 find_flag = textEdit->find(str_key, QTextDocument::FindBackward); 414 } 415 } 416 if (!find_flag) { 417 QMessageBox::information(this, "结果", "没有找到查找内容", QMessageBox::Yes); 418 } 419 } 420 } 421 //替换 422 void MainWindow::findReplace(QString find_str, bool ignore_flg) 423 { 424 /* 425 * 参数find_str:查找关键字 426 * 参数ignore_flg:区分大小写 427 */ 428 bool find_flag; 429 if (ignore_flg) { 430 find_flag = textEdit->find(find_str, QTextDocument::FindCaseSensitively); 431 } else { 432 find_flag = textEdit->find(find_str); 433 } 434 if (!find_flag) { 435 QMessageBox::information(this, "结果", "没有找到查找内容", QMessageBox::Yes); 436 } else { 437 find = true; 438 } 439 } 440 void MainWindow::replaceCur(QString find_str, QString replace_str) 441 { 442 /* 443 * 参数find_str:查找的关键字; 444 * 参数replace_str:替换的关键字 445 */ 446 QTextCursor text_cursor; 447 if (find) { 448 text_cursor = textEdit->textCursor(); 449 text_cursor.insertText(replace_str); 450 } else { 451 QMessageBox::information(this, "结果", "没有内容,不能替换"+find_str, QMessageBox::Yes); 452 } 453 find = false; 454 } 455 void MainWindow::replaceAll(QString find_str, QString replace_str, bool ignore_flg) 456 { 457 /* 458 * 参数find_str:查找关键字 459 * 参数replace_str:替换关键字 460 * 参数ignore_flg:是否忽略大小写 461 */ 462 QTextCursor text_cursor; 463 if (!ignore_flg) { 464 bool haf = textEdit->find(find_str); 465 if (haf) { 466 text_cursor = textEdit->textCursor(); 467 text_cursor.insertText(replace_str); 468 while (textEdit->find(find_str)) { 469 text_cursor = textEdit->textCursor(); 470 text_cursor.insertText(replace_str); 471 } 472 while (textEdit->find(find_str, QTextDocument::FindBackward)) { 473 text_cursor = textEdit->textCursor(); 474 text_cursor.insertText(replace_str); 475 } 476 } else { 477 QMessageBox::information(this, "结果", "没有内容,不能替换"+find_str, QMessageBox::Yes); 478 } 479 } else { 480 bool haf = textEdit->find(find_str, QTextDocument::FindCaseSensitively); 481 if (haf) { 482 text_cursor = textEdit->textCursor(); 483 text_cursor.insertText(replace_str); 484 while (textEdit->find(find_str, QTextDocument::FindCaseSensitively)) { 485 text_cursor = textEdit->textCursor(); 486 text_cursor.insertText(replace_str); 487 } 488 while (textEdit->find(find_str, QTextDocument::FindCaseSensitively|QTextDocument::FindBackward)) { 489 text_cursor = textEdit->textCursor(); 490 text_cursor.insertText(replace_str); 491 } 492 } else { 493 QMessageBox::information(this, "结果", "没有内容,不能替换"+find_str, QMessageBox::Yes); 494 } 495 } 496 } 497 498 void MainWindow::slot_judge_text_state() 499 { 500 if (textEdit->toPlainText().isEmpty()) { 501 menu_edit_undo->setEnabled(false); 502 menu_edit_cut->setEnabled(false); 503 menu_edit_copy->setEnabled(false); 504 menu_edit_delete->setEnabled(false); 505 } else { 506 menu_edit_undo->setEnabled(true); 507 menu_edit_cut->setEnabled(true); 508 menu_edit_copy->setEnabled(true); 509 menu_edit_delete->setEnabled(true); 510 } 511 } 512 513 void MainWindow::slot_cursor_change_state() 514 { 515 /* 添加状态栏 */ 516 int pos; 517 pos = textEdit->textCursor().position(); 518 sbar_str = QString("第%1个字符").arg(pos); 519 sbar->showMessage(sbar_str); 520 } 521 522 MainWindow::~MainWindow() 523 { 524 525 }
replacedialog.cpp

1 #include "replacedialog.h" 2 #include3 #include 4 5 replacedialog::replacedialog(QWidget *parent) : QDialog(parent) 6 { 7 find_label = new QLabel("替换内容"); 8 replace_label = new QLabel("替换为"); 9 find_str = new QLineEdit(); 10 replace_str = new QLineEdit(); 11 find_next_button = new QPushButton("查找下一个"); 12 replace_one_button = new QPushButton("替换"); 13 replace_all_button = new QPushButton("全部替换"); 14 cancel_button = new QPushButton("取消"); 15 ignore_flag = new QCheckBox("区分大小写"); 16 17 QGridLayout *gridly = new QGridLayout(this); 18 QVBoxLayout *vboxly = new QVBoxLayout(); 19 20 vboxly->addWidget(replace_all_button); 21 vboxly->addWidget(cancel_button); 22 gridly->addWidget(find_label, 0, 0); 23 gridly->addWidget(find_str, 0, 1); 24 gridly->addWidget(find_next_button, 0, 2); 25 gridly->addWidget(replace_label, 1, 0); 26 gridly->addWidget(replace_str, 1, 1); 27 gridly->addWidget(replace_one_button, 1, 2); 28 gridly->addWidget(ignore_flag, 2, 1); 29 gridly->addLayout(vboxly, 2, 2); 30 31 find_str->setText(""); 32 replace_str->setText(""); 33 find_next_button->setEnabled(false); 34 replace_one_button->setEnabled(false); 35 replace_all_button->setEnabled(false); 36 37 this->setMaximumSize(350, 150); 38 this->setMinimumSize(300, 100); 39 40 connect(find_str, &QLineEdit::textChanged, this, &replacedialog::slot_choose_str); 41 connect(cancel_button, &QPushButton::clicked, this, &replacedialog::close); 42 connect(find_next_button, &QPushButton::clicked, this, &replacedialog::slot_find_button_state); 43 connect(replace_one_button, &QPushButton::clicked, this, &replacedialog::slot_replace_one_button_state); 44 connect(replace_all_button, &QPushButton::clicked, this, &replacedialog::slot_repalce_all_button_state); 45 46 } 47 48 void replacedialog::slot_choose_str() 49 { 50 if (!find_str->text().isEmpty()) { 51 find_next_button->setEnabled(true); 52 replace_one_button->setEnabled(true); 53 replace_all_button->setEnabled(true); 54 } else { 55 find_next_button->setEnabled(false); 56 replace_one_button->setEnabled(false); 57 replace_all_button->setEnabled(false); 58 } 59 } 60 void replacedialog::slot_find_button_state() 61 { 62 if (ignore_flag->isChecked()) { 63 emit signal_findReplaceStr(find_str->text(), true); 64 } else { 65 emit signal_findReplaceStr(find_str->text(), false); 66 } 67 } 68 void replacedialog::slot_replace_one_button_state() 69 { 70 emit signal_replaceCurOneStr(find_str->text(), replace_str->text()); 71 } 72 void replacedialog::slot_repalce_all_button_state() 73 { 74 if (ignore_flag->isChecked()) { 75 emit signal_replaceAllStr(find_str->text(), replace_str->text(), true); 76 } else { 77 emit signal_replaceAllStr(find_str->text(), replace_str->text(), false); 78 } 79 }
代码说明:
(1)撤销、剪切、复制、粘贴、全选最好使用QTextEdit自带的槽函数,自己去实现比较麻烦。
1 connect(menu_edit_undo, &QAction::triggered, textEdit, &textEdit->undo); //使用QTextEdit自带的槽函数 2 connect(menu_edit_cut, &QAction::triggered, textEdit, &textEdit->cut); 3 connect(menu_edit_copy, &QAction::triggered, textEdit, &textEdit->copy); 4 connect(menu_edit_paste, &QAction::triggered, textEdit, &textEdit->paste); 5 connect(menu_edit_all, &QAction::triggered, textEdit, &textEdit->selectAll);
(2)切换字体直接使用QFontDialog类就可以实现。
(3)打印直接使用QPrinter类就可以实现。
(4)删除功能没有QTextEdit自带的槽函数,其实可以使用剪切的功能,它们的区别在于删除之后的内容不会出现在剪贴板上。
1 textEdit->cut(); 2 clipboard->setText("");
5 存在的bug
(1)替换全部功能还存在bug,会导致程序崩溃。
(2)打开和保存的的中文编码格式使用的是默认的编码,Windows下是ANSI编码,如果打开其它编码格式的文件,例如"UTF-8"编码,则会出现乱码。
其实最好的解决方式,是在读取文本的时候,判断一下编码格式,但是怎么实现还不知道,查了一些资料,也没搞定。电脑自带的记事本就有这个功能:
(3)部分功能还没有实现:自动换行、放大、缩小、状态栏显示等。
(4)另外,肯定还有一些我不知道的bug,如果网友发现了,还请指出来。