1、UI设计,存储为MainWindow.ui文件
2、编译MainWindow.ui文件,自动生成ui_MainWindow.h文件
3、编写界面逻辑,实现类MainWindow
#ifndef QTSTUDYAPP_H
#define QTSTUDYAPP_H
#include <QtGui/QMainWindow>
#include "ui_MainWindow.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
enum{MaxRecentFilesCount = 9};
public:
MainWindow(QWidget *parent = 0, Qt::WFlags flags = 0);
~MainWindow();
private slots:
void Slot_NewDoc();
void Slot_OpenDoc();
void Slot_SaveDoc();
void Slot_SaveAsDoc();
void Slot_Close();
void Slot_OpenRecentFile();
void Slot_TextContentModified();
void Slot_Undo();
void Slot_Copy();
void Slot_Paste();
void Slot_Cut();
void Slot_SelectAll();
void Slot_CursorMoved();
void Slot_Find();
void Slot_Quit();
private:
Ui::MainWindow ui;
QLabel* m_Label1;
QLabel* m_Label2;
QDockWidget* m_DockWidget;
private:
bool m_UnTitled;
QString m_CurrentFile;
private:
QAction* m_SeparatorAct;
QAction* m_RecentFileActs[MaxRecentFilesCount];
private:
void initDockWidget();
void initStatusBar();
void initConnnect();
bool SetCurrentFile(const QString& file);
bool SaveFile(const QString& file);
bool LoadFile(const QString& file);
bool maybeSave();
void UpdateRecentFiles();
};
#endif // QTSTUDYAPP_H
#include "stdafx.h"
#include "mainwindow.h"
#include "findfileform.h"
MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
initDockWidget();
initStatusBar();
initConnnect();
showMaximized();
m_UnTitled = true;
m_CurrentFile = tr("untitled");
setWindowTitle(m_CurrentFile + "[*]");
}
MainWindow::~MainWindow()
{
}
void MainWindow::initDockWidget()
{
m_DockWidget = new QDockWidget(tr("查找文件"),this);
FindFileForm* findFileWidget = new FindFileForm();
m_DockWidget->setWidget(findFileWidget);
m_DockWidget->setVisible(false);
addDockWidget(Qt::RightDockWidgetArea,m_DockWidget);
}
void MainWindow::initStatusBar()
{
m_Label1 = new QLabel(tr(""));
m_Label1->setMinimumSize(200,25);
m_Label1->setFrameShape(QFrame::WinPanel);
m_Label1->setFrameShadow(QFrame::Sunken);
m_Label2 = new QLabel(tr(""));
m_Label2->setMinimumSize(200,25);
m_Label2->setFrameShape(QFrame::WinPanel);
m_Label2->setFrameShadow(QFrame::Sunken);
ui.statusBar->addWidget(m_Label1);
ui.statusBar->addWidget(m_Label2);
}
void MainWindow::initConnnect()
{
connect(ui.action_Close,SIGNAL(triggered()),this,SLOT(Slot_Close()));
connect(ui.action_Copy,SIGNAL(triggered()),this,SLOT(Slot_Copy()));
connect(ui.action_Cut,SIGNAL(triggered()),this,SLOT(Slot_Cut()));
connect(ui.action_Find,SIGNAL(triggered()),this,SLOT(Slot_Find()));
connect(ui.action_New,SIGNAL(triggered()),this,SLOT(Slot_NewDoc()));
connect(ui.action_Open,SIGNAL(triggered()),this,SLOT(Slot_OpenDoc()));
connect(ui.action_Paste,SIGNAL(triggered()),this,SLOT(Slot_Paste()));
connect(ui.action_Quit,SIGNAL(triggered()),this,SLOT(Slot_Quit()));
connect(ui.action_Save,SIGNAL(triggered()),this,SLOT(Slot_SaveDoc()));
connect(ui.actionSaveAs,SIGNAL(triggered()),this,SLOT(Slot_SaveAsDoc()));
connect(ui.action_SelectAll,SIGNAL(triggered()),this,SLOT(Slot_SelectAll()));
connect(ui.action_Undo,SIGNAL(triggered()),this,SLOT(Slot_Undo()));
connect(ui.textEdit,SIGNAL(ui.textEdit->contentsChanged()),this,SLOT(Slot_TextContentModified()));
connect(ui.textEdit,SIGNAL(ui.textEdit->cursorPositionChanged()),this,SLOT(Slot_CursorMoved()));
m_SeparatorAct = ui.menu_F->insertSeparator(ui.action_Quit);
m_SeparatorAct->setVisible(false);
for (int i = 0; i < MaxRecentFilesCount;i++)
{
m_RecentFileActs[i] = new QAction(this);
ui.menu_F->insertAction(m_SeparatorAct,m_RecentFileActs[i]);
m_RecentFileActs[i]->setVisible(false);
connect(m_RecentFileActs[i],SIGNAL(triggered()),this,SLOT(Slot_OpenRecentFile()));
}
}
void MainWindow::Slot_NewDoc()
{
maybeSave();
m_UnTitled = true;
m_CurrentFile = tr("untitled");
setWindowTitle(m_CurrentFile + "[*]");
ui.textEdit->clear();
ui.textEdit->setVisible(true);
setWindowModified(false);
}
void MainWindow::Slot_OpenDoc()
{
QString fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty())
{
maybeSave();
if (LoadFile(fileName))
{
m_Label2->setText(tr("已经读取"));
}
}
ui.textEdit->setVisible(true);
}
void MainWindow::Slot_SaveDoc()
{
if(m_UnTitled)
{
Slot_SaveAsDoc();
}
else
{
SaveFile(m_CurrentFile);
}
}
void MainWindow::Slot_SaveAsDoc()
{
QString fileName = QFileDialog::getSaveFileName(this,tr("另存为"),m_CurrentFile);
if(!fileName.isEmpty())
{
SaveFile(fileName);
}
}
void MainWindow::Slot_Undo()
{
ui.textEdit->undo();
}
void MainWindow::Slot_Copy()
{
ui.textEdit->copy();
}
void MainWindow::Slot_Paste()
{
ui.textEdit->paste();
}
void MainWindow::Slot_Cut()
{
ui.textEdit->cut();
}
void MainWindow::Slot_SelectAll()
{
ui.textEdit->selectAll();
}
void MainWindow::Slot_Close()
{
maybeSave();
ui.textEdit->setVisible(false);
}
void MainWindow::Slot_Find()
{
m_DockWidget->show();
m_DockWidget->setFloating(false);
}
void MainWindow::Slot_Quit()
{
Slot_Close();
qApp->quit();
}
void MainWindow::Slot_OpenRecentFile()
{
QAction* action = qobject_cast<QAction*>(sender());
if(action)
LoadFile(action->data().toString());
}
void MainWindow::Slot_TextContentModified()
{
setWindowModified(ui.textEdit->document()->isModified());
m_Label2->setText(tr("正在修改"));
}
void MainWindow::Slot_CursorMoved()
{
int pageCount = ui.textEdit->document()->pageCount();
QTextCursor cursor = ui.textEdit->textCursor();
int columnNum = cursor.columnNumber();
int rowNum = ui.textEdit->document()->blockCount();
m_Label1->setText(tr("%1页%2行%3列").arg(pageCount).arg(rowNum).arg(columnNum));
}
bool MainWindow::SetCurrentFile(const QString& file)
{
m_CurrentFile = QFileInfo(file).canonicalFilePath();
m_UnTitled = false;
setWindowTitle(m_CurrentFile + "[*]");
ui.textEdit->document()->setModified(false);
QSettings settings("709","QTStudy");
QStringList files = settings.value("recentFiles").toStringList();
files.removeAll(file);
files.prepend(file);
while (files.size() > MaxRecentFilesCount)
{
files.removeLast();
}
settings.setValue("recentFiles",files);
UpdateRecentFiles();
return false;
}
bool MainWindow::SaveFile(const QString& fileName)
{
QFile file(fileName);
if(!file.open(QFile::WriteOnly|QFile::Text))
{
QMessageBox::warning(this,tr("保存文件"),tr("无法保存文件%1:%2").arg(fileName).arg(file.errorString()));
}
else
{
QTextStream out(&file);
QApplication::setOverrideCursor(Qt::WaitCursor);
out<<ui.textEdit->toPlainText();
QApplication::restoreOverrideCursor();
SetCurrentFile(fileName);
m_Label2->setText(tr("已经保存"));
return true;
}
return true;
}
bool MainWindow::LoadFile(const QString& fileName)
{
QFile file(fileName);
if (!file.open(QFile::ReadOnly|QFile::Text))
{
QMessageBox::warning(this,tr("读取文件"),tr("无法读取文件%1:%2").arg(fileName).arg(file.errorString()));
return false;
}
QTextStream in(&file);
QApplication::setOverrideCursor(Qt::WaitCursor);
ui.textEdit->setText(in.readAll());
QApplication::restoreOverrideCursor();
SetCurrentFile(fileName);
return true;
}
bool MainWindow::maybeSave()
{
if (ui.textEdit->document()->isModified())
{
int result = QMessageBox::warning(this,tr("保存提示"),tr("是否需要保存现有文档"),QMessageBox::Yes,QMessageBox::No,QMessageBox::Cancel);
if(result == QMessageBox::Yes)
{
Slot_SaveDoc();
return true;
}
}
return false;
}
void MainWindow::UpdateRecentFiles()
{
QSettings settings("709","QTStudy");
QStringList files = settings.value("recentFiles").toStringList();
int numRecentFiles = qMin(files.size(),(int)MaxRecentFilesCount);
for (int i = 0 ; i<numRecentFiles;i++)
{
QString text = tr("%1.%2").arg(i+1).arg(files[i]);
m_RecentFileActs[i]->setText(text);
m_RecentFileActs[i]->setVisible(true);
m_RecentFileActs[i]->setData(files[i]);
}
for (int i = numRecentFiles ; i<MaxRecentFilesCount;i++)
{
m_RecentFileActs[i]->setVisible(false);
}
m_SeparatorAct->setVisible(numRecentFiles > 0);
}
4、编译mainwindow.h头文件,自动生成moc_mainwindow.cpp源文件
5、编写主函数展示效果
#include "stdafx.h"
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTextCodec::setCodecForTr(QTextCodec::codecForName("gb18030"));
MainWindow mainWindow;
mainWindow.show();
return app.exec();
}
6、基本效果图
7、基本能力总结
具备一个软件的基本框架
菜单栏、工具栏、状态栏、中心部件、停靠部件等基本元素都具备
可以进行简单的文档的打开、编辑、存储、undo\redo
8、不足之处
还需要改进下中心部件的实现方式,支持多文档