异度部落格

学习是一种生活态度。

0%

用于正则表达式,通配符,完整匹配三种方式

stringmatch.h

#ifndef STRINGMATCH_H
#define STRINGMATCH_H
#include <QtGui/QDialog>
class QComboBox;
class QLabel;
class QLineEdit;
class QListView;
class QSortFilterProxyModel;
class QStringListModel;
namespace Ui
{
class StringMatch;
}
class StringMatch : public QDialog
{
Q_OBJECT
public:
StringMatch(QWidget *parent = 0);
~StringMatch();
private slots:
void reapplyFilter();
private:
Ui::StringMatch *ui;
QStringListModel *sourceModel;
QSortFilterProxyModel *proxyModel;
QListView *listView;
QLabel *filterLabel;
QLabel *syntaxLabel;
QLineEdit *filterLineEdit;
QComboBox *syntaxComboBox;
};
#endif // STRINGMATCH_H

stringmatch.cpp

#include <QtGui>
#include "stringmatch.h"
#include "ui_stringmatch.h"
StringMatch::StringMatch(QWidget *parent)
: QDialog(parent), ui(new Ui::StringMatch)
{
ui->setupUi(this);
QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));
//sourceModel
sourceModel = new QStringListModel(this);
sourceModel->setStringList(QColor::colorNames());
//proxyModel
proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(sourceModel);
proxyModel->setFilterKeyColumn(0);
//listView
listView = new QListView;
listView->setModel(proxyModel);
listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
//filter
filterLabel = new QLabel(tr("要匹配的字符串"));
filterLineEdit = new QLineEdit;
filterLabel->setBuddy(filterLineEdit);
//syntax
syntaxLabel = new QLabel("匹配方式选择");
syntaxComboBox = new QComboBox;
syntaxComboBox->addItem("正则表达式",QRegExp::RegExp); //A rich Perl-like pattern matching syntax. This is the default.
syntaxComboBox->addItem("通配符",QRegExp::Wildcard); //This provides a simple pattern matching syntax similar to that used by shells (command interpreters) for "file globbing".
syntaxComboBox->addItem("完全匹配",QRegExp::FixedString); //This is equivalent to using the RegExp pattern on a string in which all metacharacters are escaped using
//当filterLineEdit和syntaxComboBox
connect(filterLineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(reapplyFilter()));
connect(syntaxComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(reapplyFilter()));
//布局
QGridLayout *layout = new QGridLayout;
layout->addWidget(listView,0,0,1,2);
layout->addWidget(filterLabel,1,0);
layout->addWidget(filterLineEdit,1,1);
layout->addWidget(syntaxLabel,2,0);
layout->addWidget(syntaxComboBox,2,1);
setLayout(layout);
setWindowTitle(tr("String Matching"));
}
StringMatch::~StringMatch()
{
delete ui;
}
void StringMatch::reapplyFilter()
{
QRegExp::PatternSyntax syntax = QRegExp::PatternSyntax(syntaxComboBox->itemData(
syntaxComboBox->currentIndex()).toInt());
QRegExp regExp(filterLineEdit->text(),Qt::CaseInsensitive,syntax);
proxyModel->setFilterRegExp(regExp);
}

软件截图: image


直到今天才把 Qt4 的中文乱码搞定太尴尬了.......鄙视下自己..... 只要程序中加入 QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale()); QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));

当然要看情况来说,你的环境可能是 GBK 或者其他的...

这个主要是编码的问题,我用的 Ubuntu,貌似 XP 就没有这个问题,蛮发下....

只要在程序种加上这两句:

QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));

具体编码要看具体环境了,可能是 GBK 或者 GB18030 或者其他的.....

PS:今天才搞懂,BS 自己阿....

今天晚上突然想到,前几天写那个 MDI Editor 少了拖拽功能支持,这里补充一下....

主要是对 Editor 类进行补充

在 editor.h 添加

//拖放
void dragEnterEvent(QDragEnterEvent *event);
void dropEvent(QDropEvent *event);

在 editor.cpp 添加

/**
拖放的两个Event
*/
void Editor::dragEnterEvent(QDragEnterEvent *event)
{
if(event->mimeData()->hasFormat("text/uri-list"))
event->acceptProposedAction();
}
void Editor::dropEvent(QDropEvent *event)
{
QList<QUrl> urls = event->mimeData()->urls();
if(urls.isEmpty())
return ;
QString fileName = urls.first().toLocalFile();
if (fileName.isEmpty())
return ;
if(readFile(fileName))
setWindowTitle(tr("%1").arg(fileName));
}

OK.

PS:晚上才发现,我的工程名居然打错了..mdieditor 打成 mideditor 了...好尴尬...算了不改了,有不影响学习交流

1,把 ubuntu->winboot 文件夹下 wubidr 和 wubidr.mbr 两个文件拷到 C 盘根目录下

2,打开 boot.ini 文件,添加 c:/wubildr.mbf= "Ubuntu",保存修改

PS:boot.ini 在 C 盘的根目录下,要是看不到,进入文件夹选项,去掉“隐藏受保护的操作系统文件”选项,选中"显示所有文件和文件夹",就可以看到 boot.ini 了

下载地址:http://www.libfetion.cn/Linux_demoapp_download.html

如果不能运行安装依赖

sudo apt-get install libcurl3
sudo apt-get install automake libc-dev g++ libcurl4-openssl-dev
sudo apt-get install build-essential
sudo apt-get install libcurl4-dev

这个脚本以前就写好了,一直没有时间放上来,由于没有学过 Vim 的脚本语法,可能写得有点 ws,大牛们不要鄙视啊...

不过这个脚本依然存在 bug,就是跳转指令后面的标号不能高亮,这个应该是正则表达式的问题,由于没学过,自己看了资料还是没办法接解决,希望大牛们能给点意见啊.

脚本如下:

" Vim syntax file
" Language: MCS-51 Assembler (A51)
" Maintainer: Killua

if version < 600
syntax clear
elseif exists("b:current_syntax")
finish
endif

setlocal iskeyword=a-z,A-Z,48-57,.,_
setlocal isident=a-z,A-Z,48-57,.,_
syn case ignore

"Working Register
syn keyword a51WorkReg r0 r1 r2 r3 r4 r5 r6 r7

"Special Function Registers
syn keyword a51SFR p0 p0.0 p0.1 p0.2 p0.3 p0.4 p0.5 p0.6 p0.7
syn keyword a51SFR p1 p1.0 p1.1 p1.2 p1.3 p1.4 p1.5 p1.6 p1.7
syn keyword a51SFR p2 p2.0 p2.1 p2.2 p2.3 p2.4 p2.5 p2.6 p2.7
syn keyword a51SFR p3 p3.0 p3.1 p3.2 p3.3 p3.4 p3.5 p3.6 p3.7
syn keyword a51SFR SP dpl dph dptr pcon
syn keyword a51SFR tcon tf1 tr1 tf0 tr0 ie1 it1 ie0 it0
syn keyword a51SFR tmod tl0 tl1 th0 th1
syn keyword a51SFR scon sm0 sm1 sm2 ren tb8 rb8 ti ri
syn keyword a51SFR sbuf
syn keyword a51SFR ie ea et2 es et1 ex1 et0 ex0
syn keyword a51SFR ip pt2 ps pt1 px1 pt0 px0
syn keyword a51SFR psw cy ac f0 rs1 rs0 ov p
syn keyword a51SFR a acc.0 acc.1 acc.2 acc.3 acc.4 acc.5 acc.6 acc.7
syn keyword a51SFR b b.0 b.1 b.2 bc.3 b.4 b.5 b.6 bc.7

" Instruction
syn keyword a51Instr mov movx movc push pop xch xchd swap

syn keyword a51Instr add addc subb inc dec mul div da

syn keyword a51Instr clr setb cpl rl rlc rr rrc anl orl xrl

syn keyword a51Instr lcall acall ret reti ajmp sjmp ljmp nop jb jnb

syn keyword a51Instr jz jnz cjne djnz

syn keyword a51Prefix cseg at db ds end

"Symbol
syn match a51Symbol "[@#]"
syn match a51Symbol "[()|/[/]:]"

"Label
syn match a51Label "^/s*[^; /t]/+:"
syn match a51Label "[$]"

" Numbers
syn match a51BinaryNumber "/<[01]/+b/>"
syn match a51HexNumber "/</d/x*h/>"
syn match a51HexNumber "/</(0x/|$/)/x*/>"
syn match a51OctalNumber "/</(0/o/+o/=/|/o/+o/)/>"
syn match a51DecimalNumber "/</(0/|[1-9]/d*/)/>"

" Comment
syn region a51Comment start=";" end="$"
" String
syn region a51String start="/"" end="/"/|$"
syn region a51String start="'" end="'/|$"

"define link
hi def link a51BinaryNumber a51Number
hi def link a51HexNumber a51Number
hi def link a51OctalNumber a51Number
hi def link a51DecimalNumber a51Number

hi def link a51WorkReg a51Keyword
hi def link a51SFR a51Keyword

" Colors
hi a51Comment guifg=#0033FF
hi a51Keyword guifg=#339933
hi a51Number guifg=#FF00FF
hi a51Symbol guifg=#FF00FF
hi a51String guifg=#FF00FF
hi a51Instr guifg=#0000CC
hi a51Label guifg=#FF0000
hi a51Prefix guifg=#9933CC

let b:current_syntax = "a51"
" vim: ts=8 sw=8 :

添加方法:

将脚本复制到 Vim 目录下的 syntax 文件夹里面

添加到列表里面

修改 synmenu.vim

" The following menu items are generated by makemenu.vim.
" The Start Of The Syntax Menu

an 50.20.100 &Syntax.C :cal SetSyn("c")<CR>
an 50.20.110 &Syntax.C++ :cal SetSyn("cpp")<CR>
an 50.20.120 &Syntax.A51 :cal SetSyn("a51")<CR>

" The End Of The Syntax Menu

列表里面的语法脚本应该茫茫多,只要加在他们后面就可以了,至于 50.20.120,自己把握放到适当位置.

系统:Ubuntu 9.04

Qt 版本:4.5.1

开发工具:Qt Creator 1.1

该软件,主要实现一个定时器的功能,最多可以定时一个小时,界面有点丑,大家不要鄙视阿....

部分代码如下:

timer.h

#ifndef TIMER_H
#define TIMER_H
#include <QtGui/QWidget>
#include <QDateTime>
class QTimer;
namespace Ui
{
class Timer;
}
class Timer : public QWidget
{
Q_OBJECT
public:
Timer(QWidget *parent = 0);
~Timer();
void setTimer(int secs);
int getTimer() const;
void draw(QPainter *painter);
signals:
void timeout();
protected:
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event);
private:
Ui::Timer *ui;
QDateTime finishTime;
QTimer *updateTimer;
QTimer *finishTimer;
};
#endif // TIMER_H

timer.cpp

#include <QtGui>
#include <cmath>
#include "timer.h"
#include "ui_timer.h"
#ifndef PI
#define PI acos(-1)
#endif
const double DegressPerMinute = 6.0; //每分钟转过6度
const double DegressPerSecond = DegressPerMinute / 60; //每秒转过7/60度
const int MaxMinutes = 60; //最大分钟数
const int MaxSeconds = MaxMinutes * 60; //最大秒钟数
const int UpdateInterval = 5; //定时器显示更新间隔
/**
构造函数
*/
Timer::Timer(QWidget *parent)
: QWidget(parent), ui(new Ui::Timer)
{
ui->setupUi(this);
finishTime = QDateTime::currentDateTime();
updateTimer = new QTimer(this);
connect(updateTimer,SIGNAL(timeout()),this,SLOT(update())); //updateTimer 到时间自动更新
finishTimer = new QTimer(this);
finishTimer->setSingleShot(true); //This property holds whether the timer is a single-shot timer.
connect(finishTimer,SIGNAL(timeout()),this,SIGNAL(timeout()));
connect(finishTimer,SIGNAL(timeout()),updateTimer,SLOT(stop())); //到时间,updateTimer 停止
//字体设置
QFont font;
font.setPointSize(8);
setFont(font);
}
/**
析构函数
*/
Timer::~Timer()
{
delete ui;
}
/**
设置定时器时间
*/
void Timer::setTimer(int secs)
{
secs = qBound(0, secs, MaxSeconds); //Returns value bounded by min and max. This is equivalent to qMax(min, qMin(value, max)).
finishTime = QDateTime::currentDateTime().addSecs(secs);
if(secs > 0) {
updateTimer->start(UpdateInterval * 1000); //单位是ms,所以要乘以1000
finishTimer->start(secs * 1000);
} else {
updateTimer->stop();
finishTimer->stop();
}
update();
}
/**
返回剩余时间
*/
int Timer::getTimer() const
{
int secs = QDateTime::currentDateTime().secsTo(finishTime); //返回两个日期相差的秒数
if(secs < 0)
secs = 0;
return secs;
}
/**
鼠标按下事件
*/
void Timer::mousePressEvent(QMouseEvent *event)
{
QPointF point = event->pos() - rect().center();
double angle = std::atan2(-point.x(), -point.y()) * 180.0 /PI;
setTimer(getTimer() + int(angle / DegressPerSecond));
update();
}
/**
绘制事件
*/
void Timer::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing,true); //Sets the given render hint on the painter if on is true; otherwise clears the render hint.
int side = qMin(width(),height()); //边长
painter.setViewport((width() - side) / 2,(height() - side) / 2, side, side); //设置显示格式,使其为一个正方形
painter.setWindow(-50,-50,100,100); //设置窗口坐标系
draw(&painter);
}
/**
绘制定时器
*/
void Timer::draw(QPainter *painter)
{
static const int triangle[3][2] = { {-2,-49} ,{2,-49}, {0,-47} };
QPen thickPen(palette().foreground(),1.5); //palette:调色板
QPen thinPen(palette().foreground(),0.5);
//绘制定时器顶部的三角形
painter->setPen(thinPen);
painter->setBrush(palette().foreground());
painter->drawPolygon(QPolygon(3,&triangle[0][0]));
//圆锥形渐变色中心为(0,0)旋转角为-90度
QConicalGradient coneGradient(0,0,-90.0);
coneGradient.setColorAt(0.0,Qt::darkGray);
coneGradient.setColorAt(0.2,Qt::blue);
coneGradient.setColorAt(0.5,Qt::white);
coneGradient.setColorAt(1.0,Qt::darkGray);
//绘制表盘
painter->setBrush(coneGradient);
painter->drawEllipse(-46,-46,92,92);
//辐射形渐变色中心为(0,0,) 半径20 焦点(0,0,)
QRadialGradient radialGradient(0,0,20,0,0);
radialGradient.setColorAt(0.0, Qt::lightGray);
radialGradient.setColorAt(0.8,Qt::darkGray);
radialGradient.setColorAt(0.9,Qt::white);
radialGradient.setColorAt(1.0,Qt::black);
//绘制内盘
painter->setPen(Qt::NoPen);
painter->setBrush(radialGradient);
painter->drawEllipse(-20,-20,40,40);
//线性渐变色
QLinearGradient linearGradient(-7, -25 ,7 ,-25);
linearGradient.setColorAt(0.0, Qt::black);
linearGradient.setColorAt(0.3, Qt::lightGray);
linearGradient.setColorAt(0.8, Qt::white);
linearGradient.setColorAt(1.0, Qt::black);
//绘制指针
painter->rotate(getTimer() * DegressPerSecond);
painter->setBrush(linearGradient);
painter->setPen(thinPen);
painter->drawRoundRect(-7,-25,14,50,170,150);
//绘制表盘刻度
for (int i = 0; i<=MaxMinutes-1; ++i) { //MaxMinutes-1防止60与0重合
if( i % 5 == 0) {
painter->setPen(thickPen);
painter->drawLine(0,-41,0,-44);
painter->drawText(-15,-41,30,30,Qt::AlignHCenter | Qt::AlignTop,QString::number(i));
} else {
painter->setPen(thinPen);
painter->drawLine(0,-42,0,-44);
}
painter->rotate(-DegressPerMinute);
}
}

界面截图如下:

image

PS:最近电脑经常出问题,看来是 RP 太差了....

没话说...直接贴代码

splitereditor.h

#ifndef SPLITEREDITOR_H
#define SPLITEREDITOR_H
#include <QtGui/QWidget>
class QSplitter;
class QTextEdit;
namespace Ui
{
class SpliterEditor;
}
class SpliterEditor : public QWidget
{
Q_OBJECT
public:
SpliterEditor(QWidget *parent = 0);
~SpliterEditor();
private:
Ui::SpliterEditor *ui;
QSplitter *splitter;
QTextEdit *editor1;
QTextEdit *editor2;
QTextEdit *editor3;
};
#endif // SPLITEREDITOR_H

splitereditor.cpp

#include <QtGui>
#include "splitereditor.h"
#include "ui_splitereditor.h"
SpliterEditor::SpliterEditor(QWidget *parent)
: QWidget(parent), ui(new Ui::SpliterEditor)
{
ui->setupUi(this);
splitter = new QSplitter(Qt::Horizontal);
editor1 = new QTextEdit;
editor2 = new QTextEdit;
editor3 = new QTextEdit;
splitter->addWidget(editor1);
splitter->addWidget(editor2);
splitter->addWidget(editor3);
editor1->setPlainText("Killua");
editor2->setPlainText("KK");
editor3->setPlainText("Hello World");
splitter->show();
}
SpliterEditor::~SpliterEditor()
{
delete ui;
}

无聊学习着......

写一个 Ticker,练习下事件触发

部分代码如下:

ticker.h

#ifndef TICKER_H
#define TICKER_H
#include <QtGui/QWidget>
namespace Ui
{
class Ticker;
}
class Ticker : public QWidget
{
Q_OBJECT
public:
Ticker(QWidget *parent = 0);
~Ticker();
void setText(const QString &newText);
QString text() const ;
QSize sizeHint() const;
protected:
void paintEvent(QPaintEvent *event);
void timerEvent(QTimerEvent *evnet);
void showEvent(QShowEvent *event);
void hideEvent(QHideEvent *event);
private:
Ui::Ticker *ui;
QString tickerText;
int offset; //时间间隔
int timerID; //定时器ID
};
#endif // TICKER_H

ticker.cpp

*#include <QtGui>
#include "ticker.h"
#include "ui_ticker.h"
Ticker::Ticker(QWidget *parent)
: QWidget(parent), ui(new Ui::Ticker)
{
ui->setupUi(this);
offset = 0;
timerID = 0;
}
Ticker::~Ticker()
{
delete ui;
}
/**
设置文本
*/
void Ticker::setText(const QString &newText)
{
tickerText = newText;
update();
updateGeometry();
}
/**
获取文本内容
*/
QString Ticker::text() const
{
return tickerText;
}
/**
设置Widget大小
*/
QSize Ticker::sizeHint() const
{
return fontMetrics().size(0,text()); //fontMetrics(): Returns the font metrics for the widget's current font
}
/**
绘制事件
*/
void Ticker::paintEvent(QPaintEvent *)
{
QPainter painter(this);
int textWidth = fontMetrics().width(text());
if (textWidth < 1)
return ;
int x = -offset;
while (x < width()) {
painter.drawText(x,0,textWidth,height(),Qt::AlignLeft | Qt::AlignVCenter,text()); //绘制文本
x += textWidth;
}
}
/**
定时器事件
*/
void Ticker::timerEvent(QTimerEvent *event)
{
if (event->timerId() == timerID) {
++offset;
if(offset >= fontMetrics().width(text()))
offset = 0;
scroll(-1,0); //向左滚动一个像素
} else {
QWidget::timerEvent(event);
}
}
/**
显示事件
*/
void Ticker::showEvent(QShowEvent *)
{
timerID = startTimer(30); //Starts a timer and returns a timer identifier, or returns zero if it could not start a timer.
}
/**
隐藏事件
*/
void Ticker::hideEvent(QHideEvent *)
{
killTimer(timerID);
timerID = 0;
}

界面截图如下:

image

可以自动向左滚动...(怎么感觉像楼下显示电费的....尴尬了)


继续无聊的暑假....

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

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


程序部分代码如下:

editor.h

#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

#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

#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

#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


放假了...无聊中....