您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center 汽车系统工程   模型库  
会员   
   
OCSMP认证课程:OCSMP-MU
4月9-10日 线上
基于模型的数据治理与数据中台
5月19-20日 北京+线上
网络安全原理与实践
5月21-22日 北京+线上
     
   
 订阅
  捐助
基于Qt的聊天型多功能文本编辑器
 
  196  次浏览      33
 2019-4-1
 
编辑推荐:
本文来自于csdn,本文主要通过长期使用Sublime Text3,用一个项目介绍是如何基于Qt的聊天的,希望对您的学习有帮助。

最近一入Qt就无法自拔了,为了完工这个项目,连续四五天都是一点多才睡的,加上前前后后调试总共花了我一周时间。主要实现功能有:可多人交互聊天、换肤、C/C++关键字高亮、带编译、可跳转至浏览器。

开发环境:

Qt4.8 + Linux

初衷:

做这个项目的初衷是由于长期使用Sublime Text3,萌生了想自己做一个的想法,并且想在上面添加一些自己想要的功能。不过由于个人能力有限,也删减了许多功能。

需求确定:

1、输入文本

2、保存本地

3、打开本地文件、新建文件

4、换肤

5、实时更新行列号

6、C/C++语法高亮

7、搭建聊天室服务器

8、添加聊天客户端

9、可跳转浏览器

通过将需求罗列,每天完成指定的功能,一方面能合理分配时间,另一方面也能通过各模块实现得到反馈,有继续开发的动力。

下面展示一下界面(有点简单)

1、行列号是通过光标位置来确定的

2、关键字高亮通过调用QRegExp,即正则表达式来匹配关键字符串并上色。

3、从左到右的菜单栏按钮依次是新建文件、保存文件、打开文件、换肤、编译、聊天、和Google。

前面三个功能调用Qt的QFile和QFileDialog头文件中的函数就可以完成。

换肤功能演示:

就是简单的运用信号和槽函数通过切换资源文件名来切换背景图片。

编译演示

运行的是显示当前时间的程序

如果程序出错会提示错误信息

实现原理也很简单,实际上是调用外部进程执行gcc 命令实现的(QProcess)

聊天功能:

首先要先运行服务端创建聊天室,这里采用的TCP/IP协议

客户端可以通过输入IP和账号进行连接(端口已默认设置)

联网功能就是调用URL,实际上就是一个类似超链接的过程,这里就不详细赘述了。

部分实现代码:

关键字高亮类keyhighlight:

头文件

#ifndef KEYHIGHLIGHT_H
#define KEYHIGHLIGHT_H
#include <QSyntaxHighlighter>//高亮库
#include <QTextCharFormat>//字体格式设置
#include <QTextDocument>
#include <QRegExp>//正则表达式
class Keyhighlight : public QSyntaxHighlighter
{
Q_OBJECT
public:
Keyhighlight(QTextDocument *parent = 0);
void highlightBlock(const QString &text);
private:
struct HighlightRule
{
QRegExp pattern;
QTextCharFormat format;
};
void setNormalFormat();
void setDigitalFormat();
void setFuncFormat();
void setKeywordFormat();
void setStringFormat();
void setCommentFormat();
QVector<HighlightRule> highlightRules;//高亮规则容器
QRegExp commentStartExpression;
QRegExp commentEndExpression;
//由于高亮设置会依次覆盖前面的 所以越后面优先级越高
QTextCharFormat normalFormat;//普通文本
QTextCharFormat digitalFormat;//数字
QTextCharFormat functionFormat;//函数
QTextCharFormat keywordFormat;//数据类型关键字
QTextCharFormat keywordFormat_two;//流程控制关键字
QTextCharFormat keywordFormat_three;//include关键字
QTextCharFormat stringFormat;//字符串
QTextCharFormat escFormat;//转义字符和占位符
QTextCharFormat singleLineCommentFormat;//单行注释高亮
QTextCharFormat multiLineCommentFormat;//多行注释高亮
};
#endif // KEYHIGHLIGHT_H

实现

#include "keyhighlight.h"
#include<QFont>
#include <QColor>
Keyhighlight::Keyhighlight(QTextDocument *parent)
:QSyntaxHighlighter(parent)
{
setNormalFormat();//高亮的设置会依次覆盖 因此越后面的设置优先值越高
setDigitalFormat();
setFuncFormat();
setKeywordFormat();
setStringFormat();
setCommentFormat();
}void Keyhighlight::setNormalFormat()
{
HighlightRule nmrule;//普通文本高亮规则 结构体= pattern + format
QFont nmF("Courier");//字体设置
normalFormat.setFont(nmF);//普通文本格式设置
nmrule.pattern = QRegExp(".+");//正则表达式匹配除\n的所有字符
nmrule.format = normalFormat;
highlightRules.append(nmrule);
}
void Keyhighlight::setDigitalFormat()//数字
{
HighlightRule dgrule;
QFont dgtF("Courier");
digitalFormat.setFont(dgtF);
digitalFormat.setForeground(QColor(128,0,128));//设置颜色为紫色
dgrule.pattern = QRegExp("[0-9]+");//0-9数字正则匹配
dgrule.format = digitalFormat;
highlightRules.append(dgrule);
}
void Keyhighlight::setFuncFormat()//函数名
{
HighlightRule funrule;
QFont funF("Courier");
functionFormat.setFont(funF);
functionFormat.setForeground(QColor(0,255,0));//设置颜色为绿色
funrule.pattern = QRegExp("\\b[A-Za-z0-9_]+(?=\\()");//正则匹配()前的标识符 即函数名
funrule.format = functionFormat;
highlightRules.append(funrule);
}
void Keyhighlight::setKeywordFormat()//关键字的正则匹配
{
HighlightRule keyrule;
QFont keyF("Courier");
keywordFormat.setFont(keyF);
keywordFormat.setForeground(QColor(0,191,255));//蓝色
QStringList keywordPatterns;
keywordPatterns << "\\bchar\\b" << "\\bclass\\b" <<
"\\bdouble\\b"
<< "\\benum\\b" << "\\bexplicit\\b"<<
"\\bint\\b"
<< "\\blong\\b" << "\\bshort\\b" << "\\bstruct\\b"
<< "\\btypedef\\b" << "\\btypename\\b"<< "\\bunion\\b"
<< "\\bunsigned\\b" << "\\bvoid\\b"<< "\\bauto\\b"<<"\\btemplate\\b";//数据类型关键字
foreach (const QString &pattern, keywordPatterns)
{
keyrule.pattern = QRegExp(pattern);
keyrule.format = keywordFormat;
highlightRules.append(keyrule);
}
HighlightRule key2rule;
QFont key2F("Courier");
keywordFormat_two.setFont(key2F);
keywordFormat_two.setForeground(QColor(255,0,0));//红色
QStringList keywordPatterns2;
keywordPatterns2 <<"\\bfor\\b"<<"\\bif\\b"<<"\\belse\\b"<<"\\bwhile\\b"
<<"\\bbreak\\b"
<<"\\bcontinue\\b"<<"\\bgoto\\b"<<"\\bswitch\\b"<<"\\
bcase\\b"
<<"\\bdefault\\b"<<"\\breturn\\b"<<"\\bconst\\b"<<"\\
bstatic\\b"
<<"\\bextern\\b"<<"\\bregister\\b"<<"\\bsizeof\\b"<<"

\\bvolatile\\b"
<<"\\bexplicit\\b"<<"\\boperator\\b"<<"\\btypename\\b"
<<"\\bfriend\\b"
<<"\\binline\\b"<<"\\busing\\b"<<"\\bvirtual\\b";
foreach (const QString &pattern, keywordPatterns2)
{
key2rule.pattern = QRegExp(pattern);
key2rule.format = keywordFormat_two;
highlightRules.append(key2rule);
}
HighlightRule key3rule;
QFont key3F("Courier");
keywordFormat_three.setFont(key3F);
keywordFormat_three.setForeground(QColor(255,0,0));
key3rule.pattern = QRegExp("#include\s*");
key3rule.format = keywordFormat_three;
highlightRules.append(key3rule);
}
void Keyhighlight::setStringFormat()//字符串
{
HighlightRule strrule;
QFont strF("Courier");
stringFormat.setFont(strF);
stringFormat.setForeground(QColor(255,140,0));//黄色
strrule.pattern = QRegExp("(\<([^\<]*)\>)|(\"([^\"]*)\")");

//正则匹配两个引号或三角括号之间的字符串
strrule.format = stringFormat;
highlightRules.append(strrule);
}
void Keyhighlight::setCommentFormat()//注释
{
HighlightRule cmtrule;
singleLineCommentFormat.setForeground(QColor(192,192,192));

//灰色
cmtrule.pattern = QRegExp("//[^\n]*");
cmtrule.format = singleLineCommentFormat;
highlightRules.append(cmtrule);
multiLineCommentFormat.setForeground(QColor(192,192,192));
commentStartExpression = QRegExp("/\\*");

//多行注释正则匹配开始字符
commentEndExpression = QRegExp("\\*/");//结束字符
}void Keyhighlight::highlightBlock(const QString &text)//text是单行传入的
{
foreach(const HighlightRule & rule,highlightRules)
{
QRegExp expression(rule.pattern);
int index = expression.indexIn(text);
while(index >= 0)
{
int length = expression.matchedLength();
setFormat(index,length,rule.format);
index = expression.indexIn(text,index+length);
}
}
setCurrentBlockState(0);
int startIndex = 0;
if (previousBlockState() != 1)
startIndex = commentStartExpression.indexIn(text);
while (startIndex >= 0)
{
int endIndex = commentEndExpression.indexIn(text, startIndex);
int commentLength;
if (endIndex == -1)
{
setCurrentBlockState(1);
commentLength = text.length() - startIndex;
}
else
{
commentLength = endIndex - startIndex + commentEndExpression.matchedLength();
}
setFormat(startIndex, commentLength, multiLineCommentFormat);
startIndex = commentStartExpression.indexIn(text, startIndex + commentLength);
}
}

编译功能实现

void MainWindow::onBuild()
{
onSaveFile();//先保存文件
if("" == getOpenFilePath()) return;//如果仍然不保存则直接返回
QProcess *p = new QProcess;//创建进程执行外部程序
QStringList arg1;
arg1 << getOpenFilePath();
arg1 << "-std=gnu99";
p->start("gcc",arg1/*QStringList() << getOpenFilePath()*/);//gcc filename
p->waitForFinished();//等待结束
QString s = QString::fromLocal8Bit((p->readAllStandardError()));//从本地字符集GB到Unicode的转换,获取错误信息
if(s == "")//如果错误信息为空则说明没有错
{
QProcess *p2 = new QProcess;//创建进程执行./a.out
p2->start("./a.out");
p2->waitForFinished();
s += QString::fromLocal8Bit(p2->readAllStandardOutput());
delete p2;
}
QWidget* wd = new QWidget;//新建窗口
QTextEdit* te = new QTextEdit(wd);//新建文本存放编译结果字符串
QGridLayout *grid = new QGridLayout;//添加新布局
grid->addWidget(te,0,0);
wd->setWindowTitle("编译结果");
wd->setLayout(grid);//布局
te->setPlainText(s);//设置文本
te->show();
wd->show();
delete p;
}

对此项目感兴趣可移步此处。

   
196 次浏览       33
相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程