目录
一 背景
打开文本文件后,左侧显示被打开的文件内容,右侧显示鼠标选中的文本的翻译结果,提高日志查看效率。
二 功能需求
- 打开文件: 提供选择文件路径的功能;
- 拖放文件直接打开的功能;
- 展示内容分为两部分,左侧展示源文本内容,右侧展示被鼠标选中的文本的翻译效果;
- 左右两片区域可通过中间的分割线自由拉伸宽度;
- 提供打开文件、关闭文件、设置翻译规则、帮助等几个菜单;
- 智能解析xml文件的翻译规则,制定标准模板让用户自行完成xml文件的书写;
三 软件界面开发方式
纯代码开发
四 工程文件结构
五 源代码
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include<QHBoxLayout>
#include<QSplitter>
#include<QTextEdit>
#include <QDragEnterEvent>
#include<QMimeData>
#include<QMenu>
#include<QSettings>
#include <QCoreApplication>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
QHBoxLayout *ph=NULL; //布局
QSplitter *phs=NULL;//分割器
QTextEdit *disText=NULL;//显示内容控件
QTextEdit *DisResultText=NULL;//显示翻译结果控件
QMenu *menu=NULL;
QMenuBar * menuBar=NULL ;
//打开文件、关闭文件、设置翻译规则、帮助菜单
QAction * openFiles=NULL ;
QAction * closeFiles=NULL;
QAction * setTansform=NULL ;
QAction * help=NULL;
QSettings *settings=NULL; //配置文件
//创建映射解析文件
QString path=QCoreApplication::applicationDirPath()+"/map.txt";
//重写接口: 实现文件拖放打开的功能
protected:
void dragEnterEvent(QDragEnterEvent *event); //拖放进入事件
void dropEvent(QDropEvent *event);//放下事件
private:
void initMenu(); //初始化菜单
void readTxtFile(QString path); //根据文件路径读取文本文件
private slots:
void openFile();
void closeFile();
void setT();
void helps();
void handleTxt(); //获取被选中的文本并根据规则翻译
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QFile>
#include <QList>
#include <QMenuBar>
#include <QUrl>
#include<QDebug>
#include <QFileDialog>
#include<QMessageBox>
#include <QCoreApplication>
#include<QStatusBar>
#include <QDesktopServices>
#include <QTextCursor>
#include<QTextDocument>
/*
背景: 打开文本文件后,左侧显示被打开的文件内容,右侧显示鼠标选中的文本的翻译结果,提高日志查看效率。
功能需求:
1.打开文件: 提供选择文件路径的功能;
2.拖放文件直接打开的功能;
3.展示内容分为两部分,左侧展示源文本内容,右侧展示被鼠标选中的文本的翻译效果;
4.左右两片区域可通过中间的分割线自由拉伸宽度;
5.提供打开文件、关闭文件、设置翻译规则、帮助等几个菜单;
6.智能解析xml文件的翻译规则,制定标准模板让用户自行完成xml文件的书写;
软件界面开发方式: 纯代码开发
*/
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
//设置窗口位置
setGeometry(100,100,800,600);
setWindowTitle("自定义规则实时日志文件翻译工具");
//设置菜单项
initMenu();
//窗口总布局使用水平布局
ph=new QHBoxLayout(this);
//水平分裂器
phs=new QSplitter(Qt::Horizontal,this);
//添加文本显示控件和文本翻译结果显示控件
disText=new QTextEdit;
DisResultText=new QTextEdit;
//设置内容显示控件为只读,禁止修改与删除
//disText->setReadOnly(true);
DisResultText->setReadOnly(true);
//由于drop事件是由子控件向父控件传播的,通过禁止QTextEdit控件的drop事件,
//来允许主窗口得到drop事件,我们就得到了MainWindow中的整个窗口的drop事件。
disText->setAcceptDrops(false);
this->setAcceptDrops(true);
//把控件添加到分裂器中
phs->addWidget(disText);
phs->addWidget(DisResultText);
//是否动态跳转子元素的大小
phs->setOpaqueResize(false);
//设置分割线的大小
phs->setHandleWidth(2);
//获取分割线的对象
auto QSPHandle = phs->handle(1);
//设置分割线的颜色
QSPHandle->setStyleSheet("background-color: rgb(255, 170, 0);");
//把分割器添加到水平布局中
ph->addWidget(phs);
//设置主体布局
setLayout(ph);
//设置中心部件为分割部件,以全屏展示
setCentralWidget(phs);
//绑定菜单项的信号与槽
//--------------------------------------------------------------------------------------------------------------------------------
connect(openFiles,SIGNAL(triggered()),this,SLOT(openFile()));
connect(closeFiles,SIGNAL(triggered()),this,SLOT(closeFile()));
connect(setTansform,SIGNAL(triggered()),this,SLOT(setT()));
connect(help,SIGNAL(triggered()),this,SLOT(helps()));
//文本选择区域改变信号处理
connect(disText,SIGNAL(selectionChanged()),this,SLOT(handleTxt()));
}
MainWindow::~MainWindow()
{
}
//拖放文件进入事件
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
//数据中是否包含url,如果是则接收事件,否则忽略该事件
if(event->mimeData()->hasUrls())
event->acceptProposedAction();
else event->ignore();
}
//放下事件
void MainWindow::dropEvent(QDropEvent *event)
{
//获取MIME数据
const QMimeData *mimeData=event->mimeData();
//判断数据中是否包含URL
if(mimeData->hasUrls()){
//获取URL列表
QList<QUrl> urlList=mimeData->urls();
//将其中第一个URL表示为本地文件路径
QString fileName=urlList.at(0).toLocalFile();
//-----------------------------这里需要使用多线程来进行文件的读取---------------------------------------------------------------------
//如果文件路径不为空,则读取文件
readTxtFile(fileName);
}
}
//初始化菜单
void MainWindow::initMenu()
{
menuBar = new QMenuBar(this);
menu = new QMenu("文件", menuBar);
//打开文件、关闭文件、设置翻译规则、帮助菜单
openFiles = new QAction(QIcon(":/Qt.png"), "打开文件", menu);
closeFiles = new QAction(QIcon(":/Qt.png"), "关闭文件", menu);
setTansform = new QAction(QIcon(":/Qt.png"), "设置翻译规则", menu);
help = new QAction(QIcon(":/Qt.png"), "帮助", menu);
menu->addAction(openFiles);
menu->addAction(closeFiles);
menu->addAction(setTansform);
menu->addAction(help);
menuBar->addMenu(menu);
this->setMenuBar(menuBar);
}
void MainWindow::readTxtFile(QString path)
{
if(!path.isEmpty()){
//读取文件: 以只读方式打开
QFile file(path);
if(! file.open(QIODevice::ReadOnly)) return;
//建立文本流对象,把读取到的内容显示到控件上面
QTextStream in(&file);
disText->append(in.readAll());
file.close();
}else {
return;
}
}
//打开文件
void MainWindow::openFile()
{
QString fileName = QFileDialog::getOpenFileName(this,tr("文件对话框!"), "F:",tr("日志文件(*log);" "文本文件(*txt)"));
readTxtFile(fileName);
}
void MainWindow::closeFile()
{
disText->clear();
}
void MainWindow::setT()
{
//创建配置文件
settings=new QSettings("settings.ini",QSettings::IniFormat);
//输出配置文件路径
this->statusBar()->showMessage("配置文件路径:"+settings->fileName());
qDebug()<<settings->fileName();
//通过setValue函数将键值对放在相对于的节下面
// 格式: settings->setValue("节名/键名","键值");
settings->setValue("student/name","zs");
settings->setValue("student/age","18");
settings->setValue("student/sex","male");
// 通过value获取值,格式: settings->value(""节名/键名"");
qDebug() << settings->value("student/name");
qDebug() << settings->value("student/age");
qDebug() << settings->value("student/sex").toString();
qDebug() << settings->value("student2/name");
qDebug() << settings->value("student2/age");
qDebug() << settings->value("student2/sex").toString();
QFile f(path);
//文件不存在则创建
if(f.exists()){
QDesktopServices::openUrl(QUrl(path));
}else {
if(f.open(QIODevice::ReadWrite | QIODevice::Truncate)){
qDebug()<<"文件创建成功";
QDesktopServices::openUrl(QUrl(path));
}else {
return;
}
}
if(f.isOpen()) f.close();
}
void MainWindow::helps()
{
QMessageBox::information(this,"信息提示框","帮助功能持续完善中");
}
void MainWindow::handleTxt()
{
QFile file(path);
QTextCursor cursor;
cursor = disText->textCursor();
QString str,str2;
int row,col;
QStringList list;
str2=cursor.selectedText();
qDebug()<<"选中的文本内容:"<<str2;
col = cursor.columnNumber();
row = cursor.blockNumber();
str="光标位置:"+QString::number(row+1)+"行"+QString::number(col)+"列";
qDebug()<<(str);
this->statusBar()->showMessage(str+"选中内容:"+str2);
//这里只考虑选中单行的情况,如果选中多行会多一个?号,暂无有效处理措施====================================
list=str2.split(" ");
qDebug()<<"str2:"<<str2.split("?");
//开始读取文件
if(file.exists()){
//读取文件: 以只读方式打开
if(! file.open(QIODevice::ReadOnly)) return;
//建立文本流对象,把读取到的内容显示到控件上面
QTextStream in(&file);
QStringList sf=in.readAll().split(":");
qDebug()<<"sf:"<<sf;
//记录匹配值
QString temp="";
//开始循环匹配
for (int i = 0; i < list.size(); ++i) {
for (int j = 0; j < sf.size(); ++j) {
if(list[i]==sf[j]){
temp+=sf[j+1]+" ";
}
}
}
if(! temp.isEmpty()){
DisResultText->setText(temp);
temp="";
}
}else {
return;
}
if(file.isOpen()) file.close();
}
res.qrc
<RCC>
<qresource prefix="/">
<file>Qt.png</file>
</qresource>
</RCC>
图标:
六 最终运行效果-视频演示
https://mp.csdn.net/mp_others/manage/video?spm=3001.5304
七 程序下载地址
git@gitcode.net:XiaoWang_csdn/qt_timelytransfom_gui.git