Qt_Demo_1:实现一个简易的记事本
1 环境:
系统:windows 10
代码编写运行环境:Qt Creator 4.4.1 (community)
GitHub:https://github.com/zhengcixi/Qt_Demo/tree/master/notepad
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 #include <QWidget>
5 #include <QLabel>
6 #include <QLineEdit>
7 #include <QPushButton>
8 #include <QRadioButton>
9 #include <QCheckBox>
10 #include <QGridLayout>
11 #include <QHBoxLayout>
12 #include <QGroupBox>
13 #include <QCheckBox>
14 #include <QDialog>
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 #include <QMainWindow>
5 #include <QMenuBar>
6 #include <QAction>
7 #include <QMenu>
8 #include <QTextEdit>
9 #include <QStatusBar>
10 #include <QLabel>
11 #include <QDebug>
12 #include <QString>
13 #include <QFileDialog>
14 #include <QFile>
15 #include <QMessageBox>
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 #include <QWidget>
5 #include <QDialog>
6 #include <QPushButton>
7 #include <QLabel>
8 #include <QCheckBox>
9 #include <QLineEdit>
10 #include <QGridLayout>
11 #include <QVBoxLayout>
12 #include <QString>
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 #include <QDebug>
3
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 #include <QApplication>
3
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 #include <QDialog>
3 #include <QDebug>
4 #include <QtPrintSupport/QPrinter>
5 #include <QtPrintSupport/QPrintDialog>
6 #include <QtPrintSupport/QAbstractPrintDialog>
7 #include <QPixmap>
8 #include <QTextCursor>
9 #include <QKeySequence>
10 #include <QFontDialog>
11 #include <QFont>
12 #include <QDesktopServices>
13 #include <QLatin1String>
14 #include <QTextCodec>
15 #include <QClipboard>
16 #include <QApplication>
17 #include <QTextCursor>
18 #include <QPoint>
19 #include <QTextEdit>
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<<textEdit->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<<textEdit->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<<textEdit->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<<textEdit->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 #include <QString>
3 #include <QDialog>
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,如果网友发现了,还请指出来。
Qt_Demo_1:实现一个简易的记事本的更多相关文章
- .NET Core的文件系统[5]:扩展文件系统构建一个简易版“云盘”
FileProvider构建了一个抽象文件系统,作为它的两个具体实现,PhysicalFileProvider和EmbeddedFileProvider则分别为我们构建了一个物理文件系统和程序集内嵌文 ...
- 自己来实现一个简易的OCR
来做个简易的字符识别 ,既然是简易的 那么我们就不能用任何的第三方库 .啥谷歌的 tesseract-ocr, opencv 之类的 那些玩意是叼 至少图像处理 机器视觉这类课题对我这种高中没毕业的人 ...
- 基于 getter 和 setter 撸一个简易的MVVM
Angular 和 Vue 在对Angular的学习中,了解到AngularJS 的两个主要缺点: 对于每一次界面时间,Ajax 或者 timeout,都会进行一个脏检查,而每一次脏检查又会在内部循环 ...
- C++-Qt【2】-实现一个简单的记事本
用Qt实现一个简单的记事本: #include "helloqt.h" #include <qfiledialog.h> #include <qfile.h> ...
- 探秘Tomcat——一个简易的Servlet容器
即便再简陋的服务器也是服务器,今天就来循着书本的第二章来看看如何实现一个servlet容器. 背景知识 既然说到servlet容器这个名词,我们首先要了解它到底是什么. servlet 相比你或多或少 ...
- 使用Windows Form 制作一个简易资源管理器
自制一个简易资源管理器----TreeView控件 第一步.新建project,进行基本设置:(Set as StartUp Project:View/Toolbox/TreeView) 第二步.开始 ...
- [后端人员耍前端系列]AngularJs篇:使用AngularJs打造一个简易权限系统
一.引言 上一篇博文已经向大家介绍了AngularJS核心的一些知识点,在这篇博文将介绍如何把AngularJs应用到实际项目中.本篇博文将使用AngularJS来打造一个简易的权限管理系统.下面不多 ...
- ENode 2.0 - 第一个真实案例剖析-一个简易论坛(Forum)
前言 经过不断的坚持和努力,ENode 2.0的第一个真实案例终于出来了.这个案例是一个简易的论坛,开发这个论坛的初衷是为了验证用ENode框架来开发一个真实项目的可行性.目前这个论坛在UI上是使用了 ...
- 使用MVVM框架avalon.js实现一个简易日历
最近在做公司内部的运营管理系统,因为与日历密切相关,同时无需触发条件直接显示在页面上,所以针对这样的功能场景,我就用avalon快速实现了一个简易日历,毕竟也是第一次造日历这种轮子,所以这里记录下我当 ...
- 做了一个简易的git 代码自动部署脚本
做了一个简易的git 代码自动部署脚本 http://my.oschina.net/caomenglong/blog/472665 发表于2个月前(2015-06-30 21:08) 阅读(200 ...
随机推荐
- ImportError: Cannot load backend 'TkAgg' which requires the 'tk' interactive framework, as 'headless' is currently running
MMdetection多卡训练常遇到的两个错误,百度无果,没解决,去github里mmdetection的issue模块搜索了一下找到正解. 这里记录一下,方便后者. 1️⃣ ImportError: ...
- Consul的服务注册与发现(简单介绍)
Consul的注册中心的安装及配置 1.consul下载 2.开发模式启动consul consul agent -dev 3.验证测试 通过以下地址可以访问Consul的首页: http://loc ...
- java知识点查漏补缺-- 2020513
重载和重写 方法重载(overload): 必须是同一个类 方法名(也可以叫函数)一样 参数类型不一样或参数数量不一样 方法的重写(override)两同两小一大原则: 方法名相同,参数类型相同 子类 ...
- 第3章 python 爬虫抓包与数据解析
第 3章 Python 爬虫抓包与数据解析 3.1 抓包进阶 目前,我们已经会使用 Chrome 浏览器自带的开发者工具来抓取访问网页的数据包,但是这种抓包方法有局限性,比如只能监听一个浏览器选项卡, ...
- RocketMQ 端云一体化设计与实践
简介:本文首先介绍了端云消息场景一体化的背景,然后重点分析了终端消息场景特点,以及终端消息场景支撑模型,最后对架构和存储内核进行了阐述.我们期望基于 RocketMQ 统一内核一体化支持终端和服务端不 ...
- [FAQ] edge debug栏的网络里 没有见到 All Fetch/XHR JS CSS 这些东西
一种方式是 打开调试器的设置,重置默认并刷新即可. 另一种方式是把这个 "筛选" 点掉. Tool:揭开网站所用的技术 Link:https://www.cnblogs.com ...
- WPF 框架开发 调试和开发 XAML 构建过程的 PresentationBuildTasks 方法
阅读本文,你可以了解如何编写开发和调试 XAML 构建为 Baml 和 g.cs 文件的过程和工具.本文也适合想要了解 WPF 的 XAML 构建过程的开发者阅读,本文提供了可以断点调试 WPF 的 ...
- Mobius 一个运行在 .NET Core 上的 .NET 运行时
一个 .NET 应用仅仅只是一块在 .NET 运行时上面运行的二进制代码.而 .NET 运行时只是一个能执行这项任务的程序.当前的 .NET Framework 和 .NET Core 运行时采用 C ...
- 关于Git和Svn的区别
关于Git 和 Svn 的选用,详细列出区别 Git 是分布式的,而 Svn 不是分布的; Git 把内容按元数据方式存储,而 SVN 是按文件; Git 没有一个全局版本号,而 SVN 有:目前为止 ...
- STLINK/V2下载器接线方法
一.ST-LINK ST-LINK产品如下图所示: ST-LINK接口定义如下图所示 ST-LINK与stm32接线 使用SW接法只需要四根线: STM32 ST-LINK VCC(3.3V) TVC ...