QT学习笔记之八 MDIEditor

这个程序由于期末考试搁置很久了,下午由于下大雨没出去,就把他完成了哈…..主要实现多文档编辑功能,测试了下,基本上没有bug,由于整体设计思路参考书上的,大牛们不要BS我阿…..

等下次有时间将他改成简易的代码编辑器好了,貌似国外网站上有相关模块,有时间去看看。。。。


程序部分代码如下:

editor.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef EDITOR_H
#define EDITOR_H
#include <QTextEdit>
class Editor : public QTextEdit
{
Q_OBJECT
public:
Editor(QWidget *parent=0);
void newFile();
bool save();
bool saveAs();
QSize sizeHint() const;
QAction *windowMenuAction() const { return action ;}
static Editor *open(QWidget *parent = 0);
static Editor *openFile(const QString &fileName,QWidget *parent = 0);
protected:
void closeEvent(QCloseEvent *event);
private slots:
void documentWasModified();
private:
bool okToContinue();
bool saveFile(const QString &fileName);
void setCurrentFile(const QString &fileName);
bool readFile(const QString &fileName);
bool writeFile(const QString &fileName);
QString strippedName(const QString &fullFileName);
QString curFile;
bool isUntitled;
QAction *action;
};
#endif // EDITOR_H

editor.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#include <QtGui>
#include "editor.h"
/**
构造函数
*/
Editor::Editor(QWidget *parent) :QTextEdit(parent)
{
action = new QAction(this);
action->setCheckable(true);
connect(action,SIGNAL(triggered()),this,SLOT(show()));
connect(action,SIGNAL(triggered()),this,SLOT(setFocus()));
isUntitled = true;
connect(document(),SIGNAL(contentsChanged()),this,SLOT(documentWasModified()));
setWindowIcon(QPixmap(":/images/document.png"));
setWindowTitle("[*]");
setAttribute(Qt::WA_DeleteOnClose); //Makes Qt delete this widget when the widget has accepted the close event
}
/**
新建文件
*/
void Editor::newFile()
{
static int documentNumber = 1;
curFile = tr("document%1.txt").arg(documentNumber);
setWindowTitle(curFile + "[*]");
action->setText(curFile);
isUntitled= true;
++documentNumber;
}
/**
保存
*/
bool Editor::save()
{
if(isUntitled) {
return saveAs();
}
else {
return saveFile(curFile);
}
}
/**
另存为
*/
bool Editor::saveAs()
{
QString fileName = QFileDialog::getSaveFileName(this,tr("Save As"),curFile);
if(fileName.isEmpty())
return false;
return saveFile(fileName);
}
/**
大小调整
*/
QSize Editor::sizeHint() const
{
return QSize(72 * fontMetrics().width('x'),25* fontMetrics().lineSpacing()); //Returns the font metrics for the widget's current font
}
/**
打开
*/
Editor *Editor::open(QWidget *parent)
{
QString fileName = QFileDialog::getOpenFileName(parent,tr("Open"),".");
if(fileName.isEmpty())
return 0;
return openFile(fileName,parent);
}
/**
打开文件
*/
Editor *Editor::openFile(const QString &fileName,QWidget *parent)
{
Editor *editor = new Editor(parent);
if(editor->readFile(fileName)) {
editor->setCurrentFile(fileName);
return editor;
}
else {
delete editor;
return 0;
}
}
/**
关闭事件
*/
void Editor::closeEvent(QCloseEvent *event)
{
if(okToContinue()) {
event->accept();
}
else {
event->ignore();
}
}
/**
文件已被修改
*/
void Editor::documentWasModified()
{
setWindowModified(true);
}
/**
是否可以继续
*/
bool Editor::okToContinue()
{
if(document()->isModified()) {
int r=QMessageBox::warning(this,tr("MDI Editor"),
tr("File %1 has been modified./n").arg(strippedName(curFile),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel));
if(r == QMessageBox::Yes) {
save();
}
else if (r == QMessageBox::Cancel) {
return false;
}
}
return true;
}
/**
文件保存
*/
bool Editor::saveFile(const QString &fileName)
{
if (writeFile(fileName)) {
setCurrentFile(fileName);
return true;
}
else {
return false;
}
}
/**
设置为当前文件
*/
void Editor::setCurrentFile(const QString &fileName)
{
curFile = fileName;
isUntitled = false;
action->setText(strippedName(curFile));
document()->setModified(false);
setWindowTitle(strippedName(curFile)+ "[*]");
setWindowModified(false);
}
/**
读取文件
*/
bool Editor::readFile(const QString &fileName)
{
QFile file(fileName);
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //设置文件读取模式
QMessageBox::warning(this,tr("MDI Editor"),tr("Cannot read file %1:/n%2.").
arg(file.fileName()).arg(file.errorString()));
return false;
}
QTextStream in(&file);
QApplication::setOverrideCursor(Qt::WaitCursor); //设置鼠标
setPlainText(in.readAll());
QApplication::restoreOverrideCursor();
return true;
}
/**
文件写入
*/
bool Editor::writeFile(const QString &fileName)
{
QFile file(fileName);
if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::warning(this,tr("MDI Editor"),
tr("Cannot write file %1:/n%2").arg(file.fileName()).arg(file.errorString()));
return false;
}
QTextStream out(&file);
QApplication::setOverrideCursor(Qt::WaitCursor);
out<<toPlainText()
;
QApplication::restoreOverrideCursor();
return true;
}
QString Editor::strippedName(const QString &fullFileName)
{
return QFileInfo(fullFileName).fileName();
}

mainwindow.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui/QMainWindow>
class QAction;
class QActionGroup;
class QLabel;
class QMdiArea;
class QMenu;
class QToolBar;
class Editor;
namespace Ui
{
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void newFile();
void openFile(const QString &fileName);
protected:
void closeEvent(QCloseEvent *event);
private slots:
void open();
void save();
void saveAs();
void cut();
void copy();
void paste();
void about();
void updateActions();
void loadFiles();
private:
Ui::MainWindow *ui;
void createActions();
void createMenus();
void createToolBars();
void createStatusBar();
void addEditor(Editor *editor);
Editor *activeEditor();
QMdiArea *mdiArea; //The QMdiArea widget provides an area in which MDI windows are displayed
QLabel *readyLabel;
QWidgetList windows;
//Menu
QMenu *fileMenu;
QMenu *editMenu;
QMenu *windowMenu;
QMenu *helpMenu;
//ToolBar
QToolBar *fileToolBar;
QToolBar *editToolBar;
//Actions
QActionGroup *windowActionGroup;
QAction *newAction;
QAction *openAction;
QAction *saveAction;
QAction *saveAsAction;
QAction *exitAction;
QAction *cutAction;
QAction *copyAction;
QAction *pasteAction;
QAction *closeAction;
QAction *closeAllAction;
QAction *tileAction;
QAction *cascadeAction;
QAction *nextAction;
QAction *previousAction;
QAction *separatorAction;
QAction *aboutAction;
QAction *aboutQtAction;
};
#endif // MAINWINDOW_H

mainwindos.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
#include <QtGui>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "editor.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
mdiArea = new QMdiArea;
setCentralWidget(mdiArea);
connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)),this, SLOT(updateActions()));
createActions();
createMenus();
createToolBars();
createStatusBar();
setWindowIcon(QPixmap(":/images/icon.png"));
setWindowTitle("Killua MDI Editor");
QTimer::singleShot(0,this,SLOT(loadFiles()));
}
MainWindow::~MainWindow()
{
delete ui;
}
/**
文件读取
*/
void MainWindow::loadFiles()
{
QStringList args = QApplication::arguments();
args.removeFirst();
if (!args.isEmpty()) {
foreach(QString arg,args)
openFile(arg);
mdiArea->cascadeSubWindows();
} else {
newFile();
}
mdiArea->activateNextSubWindow();
}
/**
新建文件
*/
void MainWindow::newFile()
{
Editor *editor = new Editor;
editor->newFile();
addEditor(editor);
}
/**
打开文件
*/
void MainWindow::openFile(const QString &fileName)
{
Editor *editor = Editor::openFile(fileName,this);
if(editor)
addEditor(editor);
}
/**
关闭事件
*/
void MainWindow::closeEvent(QCloseEvent *event)
{
mdiArea->closeAllSubWindows();
if(!mdiArea->subWindowList().isEmpty()) {
event->ignore();
} else {
event->accept();
}
}
/**
打开操作
*/
void MainWindow::open()
{
Editor *editor = Editor::open(this);
if(editor)
addEditor(editor);
}
/**
保存文件
*/
void MainWindow::save()
{
if(activeEditor())
activeEditor()->save();
}
/**
文件另存为
*/
void MainWindow::saveAs()
{
if (activeEditor())
activeEditor()->saveAs();
}
/**
剪切
*/
void MainWindow::cut()
{
if(activeEditor())
activeEditor()->cut();
}
/**
复制
*/
void MainWindow::copy()
{
if(activeEditor())
activeEditor()->copy();
}
/**
粘贴
*/
void MainWindow::paste()
{
if(activeEditor())
activeEditor()->paste();
}
/**
关于
*/
void MainWindow::about()
{
QMessageBox::about(this,tr("About Killua MDI Editor"),
tr("Design by Killua"));
}
/**
事件更新
*/
void MainWindow::updateActions()
{
bool hasEditor = (activeEditor()!=0);
bool hasSelection = activeEditor() && activeEditor()->textCursor().hasSelection();
saveAction->setEnabled(hasEditor);
saveAsAction->setEnabled(hasEditor);
cutAction->setEnabled(hasSelection);
copyAction->setEnabled(hasSelection);
pasteAction->setEnabled(hasEditor);
closeAction->setEnabled(hasEditor);
closeAllAction->setEnabled(hasEditor);
tileAction->setEnabled(hasEditor);
cascadeAction->setEnabled(hasEditor);
nextAction->setEnabled(hasEditor);
previousAction->setEnabled(hasEditor);
separatorAction->setEnabled(hasEditor);
if(activeEditor())
activeEditor()->windowMenuAction()->setChecked(true); //菜单栏可点击
}
/**
事件创建
*/
void MainWindow::createActions()
{
//newAction
newAction = new QAction(tr("&New"), this);
newAction->setIcon(QIcon(":/images/new.png"));
newAction->setShortcut(QKeySequence::New);
connect(newAction, SIGNAL(triggered()), this, SLOT(newFile()));
//openAction
openAction = new QAction(tr("&Open..."), this);
openAction->setIcon(QIcon(":/images/open.png"));
openAction->setShortcut(QKeySequence::Open);
connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
//saveAction
saveAction = new QAction(tr("&Save"), this);
saveAction->setIcon(QIcon(":/images/save.png"));
saveAction->setShortcut(QKeySequence::Save);
connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));
//saveAsAction
saveAsAction = new QAction(tr("Save &As..."), this);
connect(saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs()));
//exitAction
exitAction = new QAction(tr("E&xit"), this);
exitAction->setShortcut(tr("Ctrl+Q"));
connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
//cutAction
cutAction = new QAction(tr("Cu&t"), this);
cutAction->setIcon(QIcon(":/images/cut.png"));
cutAction->setShortcut(QKeySequence::Cut);
connect(cutAction, SIGNAL(triggered()), this, SLOT(cut()));
//copyAction
copyAction = new QAction(tr("&Copy"), this);
copyAction->setIcon(QIcon(":/images/copy.png"));
copyAction->setShortcut(QKeySequence::Copy);
connect(copyAction, SIGNAL(triggered()), this, SLOT(copy()));
//pasteAction
pasteAction = new QAction(tr("&Paste"), this);
pasteAction->setIcon(QIcon(":/images/paste.png"));
pasteAction->setShortcut(QKeySequence::Paste);
connect(pasteAction, SIGNAL(triggered()), this, SLOT(paste()));
//closeAction
closeAction = new QAction(tr("Cl&ose"), this);
closeAction->setShortcut(QKeySequence::Close);
connect(closeAction, SIGNAL(triggered()),mdiArea, SLOT(closeActiveSubWindow()));
//closeAllAction
closeAllAction = new QAction(tr("Close &All"), this);
connect(closeAllAction, SIGNAL(triggered()), this, SLOT(close()));
//tileAction
tileAction = new QAction(tr("&Tile"), this);
connect(tileAction, SIGNAL(triggered()),mdiArea, SLOT(tileSubWindows()));
//cacadeAction
cascadeAction = new QAction(tr("&Cascade"), this);
connect(cascadeAction, SIGNAL(triggered()),mdiArea, SLOT(cascadeSubWindows()));
//newAction
nextAction = new QAction(tr("Ne&xt"), this);
nextAction->setShortcut(QKeySequence::NextChild);
connect(nextAction, SIGNAL(triggered()),mdiArea, SLOT(activateNextSubWindow()));
//previousAction
previousAction = new QAction(tr("Pre&vious"), this);
previousAction->setShortcut(QKeySequence::PreviousChild);
connect(previousAction, SIGNAL(triggered()),mdiArea, SLOT(activatePreviousSubWindow()));
//separatorAction
separatorAction = new QAction(this);
separatorAction->setSeparator(true);
//aboutAction
aboutAction = new QAction(tr("&About"), this);
aboutAction->setStatusTip(tr("Show the application's About box"));
connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
//aboutQtAction
aboutQtAction = new QAction(tr("About &Qt"), this);
connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
windowActionGroup = new QActionGroup(this);
}
/**
菜单栏创建
*/
void MainWindow::createMenus()
{
//fileMenu
fileMenu = menuBar()->addMenu("&File");
fileMenu->addAction(newAction);
fileMenu->addAction(openAction);
fileMenu->addAction(saveAction);
fileMenu->addAction(saveAsAction);
fileMenu->addSeparator();
fileMenu->addAction(exitAction);
//editMenu
editMenu = menuBar()->addMenu(tr("&Edit"));
editMenu->addAction(cutAction);
editMenu->addAction(copyAction);
editMenu->addAction(pasteAction);
windowMenu=menuBar()->addMenu(tr("&Windos"));
windowMenu->addAction(closeAction);
windowMenu->addAction(closeAllAction);
windowMenu->addSeparator();
windowMenu->addAction(tileAction);
windowMenu->addAction(cascadeAction);
windowMenu->addSeparator();
windowMenu->addAction(nextAction);
windowMenu->addAction(previousAction);
windowMenu->addAction(separatorAction);
menuBar()->addSeparator();
helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(aboutAction);
helpMenu->addAction(aboutQtAction);
}
/**
创建工具栏
*/
void MainWindow::createToolBars()
{
fileToolBar = addToolBar(tr("FIle"));
fileToolBar->addAction(newAction);
fileToolBar->addAction(openAction);
fileToolBar->addAction(saveAction);
editToolBar = addToolBar(tr("Edit"));
editToolBar->addAction(cutAction);
editToolBar->addAction(copyAction);
editToolBar->addAction(pasteAction);
}
/**
创建状态栏
*/
void MainWindow::createStatusBar()
{
readyLabel = new QLabel(tr("Ready"));
statusBar()->addWidget(readyLabel,1);
}
/**
添加Editor
*/
void MainWindow::addEditor(Editor *editor)
{
connect(editor,SIGNAL(copyAvailable(bool)),cutAction,SLOT(setEnabled(bool)));
connect(editor,SIGNAL(copyAvailable(bool)),copyAction,SLOT(setEnabled(bool)));
QMdiSubWindow *subWindow = mdiArea->addSubWindow(editor);
windowMenu->addAction(editor->windowMenuAction());
subWindow->show();
}
/**
激活窗口
*/
Editor *MainWindow::activeEditor()
{
QMdiSubWindow *subWindow = mdiArea->activeSubWindow();
if(subWindow)
return qobject_cast<Editor *>(subWindow->widget());
return 0;
}

PS:完整源代码放到资源里面了,附上链接……

http://download.csdn.net/source/1458294


放假了…无聊中….