首页 > 数据库 >基于QScintilla项目实现SQL编辑器

基于QScintilla项目实现SQL编辑器

时间:2024-01-31 23:13:51浏览次数:30  
标签:void tr 编辑器 textEdit QScintilla SQL include MainWindow

1、下载QScintilla:
https://www.riverbankcomputing.com/static/Downloads/QScintilla/2.14.1/QScintilla_src-2.14.1.zip

2、解压缩,目录结构如下:

QScintilla_src-2.14.1
  - src 组件源代码
  - qsci 组件头文件
  - scintilla 内置的各种语言的词法扫描源代码
  - example 范例(用不到)
  - doc 文档(用不到)
  - Python 为Python提供的封装(用不到)
  - designer 为QT设计器注册QScintilla控件(用不到)

 

编译QScintilla只会用到前三个目录(src、qsci、scintilla)。

3、用QT(5.14.2)打开QScintilla工程。
工程文件:QScintilla_src-2.14.1/src/qscintilla.pro

4、构建QScintilla工程,分别用debug和release两种模式构建。
build-qscintilla-Desktop_Qt_5_14_2_MinGW_64_bit-Debug
build-qscintilla-Desktop_Qt_5_14_2_MinGW_64_bit-Release

Debug目录下的输出文件:
libqscintilla2_qt5d.a
qscintilla2_qt5d.dll

Release目录下的输出文件:
libqscintilla2_qt5.a
qscintilla2_qt5.dll

把libqscintilla2_qt5d.a改名为qscintilla2_qt5d.a
把libqscintilla2_qt5.a改名为qscintilla2_qt5.a

 

5、创建一个Demo工程,比如:QScintillaDemo
在QScintillaDemo目录下创建一个lib目录,把第4步生成的库文件拷贝过去,目录结构如下:
QScintillaDemo/lib/QScintilla/debug/qscintilla2_qt5d.a
QScintillaDemo/lib/QScintilla/debug/qscintilla2_qt5d.dll
QScintillaDemo/lib/QScintilla/release/qscintilla2_qt5.a
QScintillaDemo/lib/QScintilla/release/qscintilla2_qt5.dll

 

6、在工程文件QScintillaDemo.pro中添加如下配置:

# QScintilla
INCLUDEPATH += $$PWD/lib/QScintilla/include
DEPENDPATH += $$PWD/lib/QScintilla/include
debug {
    LIBS += -L$$PWD/lib/QScintilla/debug -lqscintilla2_qt5d
}
release {
    LIBS += -L$$PWD/lib/QScintilla/release -lqscintilla2_qt5
}

 

7、修改主窗口类MainWindow的源代码,使用QScintilla编辑器。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class QAction;
class QMenu;
class QsciScintilla;

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = nullptr);

protected:
    void closeEvent(QCloseEvent *event);

private slots:
    void newFile();
    void open();
    bool save();
    bool saveAs();
    void about();
    void documentWasModified();

private:
    void createActions();
    void createMenus();
    void createToolBars();
    void createStatusBar();
    void readSettings();
    void writeSettings();
    bool maybeSave();
    void loadFile(const QString &fileName);
    bool saveFile(const QString &fileName);
    void setCurrentFile(const QString &fileName);
    QString strippedName(const QString &fullFileName);

    QsciScintilla *textEdit;
    QString curFile;

    QMenu *fileMenu;
    QMenu *editMenu;
    QMenu *helpMenu;
    QToolBar *fileToolBar;
    QToolBar *editToolBar;
    QAction *newAct;
    QAction *openAct;
    QAction *saveAct;
    QAction *saveAsAct;
    QAction *exitAct;
    QAction *cutAct;
    QAction *copyAct;
    QAction *pasteAct;
    QAction *aboutAct;
    QAction *aboutQtAct;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"

#include <QAction>
#include <QApplication>
#include <QCloseEvent>
#include <QFile>
#include <QFileInfo>
#include <QFileDialog>
#include <QIcon>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QPoint>
#include <QSettings>
#include <QSize>
#include <QStatusBar>
#include <QTextStream>
#include <QToolBar>

#include "Qsci/qsciscintilla.h"
#include "Qsci/qscilexersql.h"
#include "Qsci/qsciapis.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow{parent}
{
    textEdit = new QsciScintilla;
    setCentralWidget(textEdit);

    createActions();
    createMenus();
    createToolBars();
    createStatusBar();

    readSettings();

    connect(textEdit, SIGNAL(textChanged()),
            this, SLOT(documentWasModified()));

    setCurrentFile("");

    //语法高亮
    QsciLexerSQL* textLexer = new QsciLexerSQL(this);
    textEdit->setLexer(textLexer);

    //自动补全
    textEdit->setAutoCompletionSource(QsciScintilla::AcsAll);
    textEdit->setAutoCompletionCaseSensitivity(false);
    textEdit->setAutoCompletionThreshold(1);

    //关键字自动补全
    QsciAPIs *apis = new QsciAPIs(textLexer);
    apis->add(QString("select"));
    apis->add(QString("from"));
    apis->add(QString("where"));
    apis->add(QString("left"));
    apis->add(QString("join"));
    apis->add(QString("and"));
    apis->prepare();

    //设置编码为UTF-8
    textEdit->SendScintilla(QsciScintilla::SCI_SETCODEPAGE, QsciScintilla::SC_CP_UTF8);

    //左侧显示行号
    textEdit->setMarginLineNumbers(0, true);
    textEdit->setMarginWidth(0, 20);

    //TAB缩进4个字符
    textEdit->setTabWidth(4);

    //当前行高亮
    textEdit->setCaretLineVisible(true);
    textEdit->setCaretLineBackgroundColor(QColor("#E8E8FF"));

    //折叠样式
    textEdit->setFolding(QsciScintilla::BoxedTreeFoldStyle);

    //初始化范例代码
    textEdit->setText("select\n\te.employee_id,\n\te.employee_name,\n\td.department_name,\n\tcase e.employee_status\n\t\twhen '0' then '在职'\n\t\twhen '1' then '离职'\n\tend as employee_status\nfrom employee_info e\njoin department_info d on d.id = e.department_id\nwhere e.deleted_flag = 0");
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if (maybeSave()) {
        writeSettings();
        event->accept();
    } else {
        event->ignore();
    }
}

void MainWindow::newFile()
{
    if (maybeSave()) {
        textEdit->clear();
        setCurrentFile("");
    }
}

void MainWindow::open()
{
    if (maybeSave()) {
        QString fileName = QFileDialog::getOpenFileName(this);
        if (!fileName.isEmpty())
            loadFile(fileName);
    }
}

bool MainWindow::save()
{
    if (curFile.isEmpty()) {
        return saveAs();
    } else {
        return saveFile(curFile);
    }
}

bool MainWindow::saveAs()
{
    QString fileName = QFileDialog::getSaveFileName(this);
    if (fileName.isEmpty())
        return false;

    return saveFile(fileName);
}

void MainWindow::about()
{
    QMessageBox::about(this, tr("About Application"),
                       tr("The <b>Application</b> example demonstrates how to "
                          "write modern GUI applications using Qt, with a menu bar, "
                          "toolbars, and a status bar."));
}

void MainWindow::documentWasModified()
{
    setWindowModified(textEdit->isModified());
}

void MainWindow::createActions()
{
    newAct = new QAction(QIcon(":/images/images/new.png"), tr("&New"), this);
    newAct->setShortcut(tr("Ctrl+N"));
    newAct->setStatusTip(tr("Create a new file"));
    connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));

    openAct = new QAction(QIcon(":/images/images/open.png"), tr("&Open..."), this);
    openAct->setShortcut(tr("Ctrl+O"));
    openAct->setStatusTip(tr("Open an existing file"));
    connect(openAct, SIGNAL(triggered()), this, SLOT(open()));

    saveAct = new QAction(QIcon(":/images/images/save.png"), tr("&Save"), this);
    saveAct->setShortcut(tr("Ctrl+S"));
    saveAct->setStatusTip(tr("Save the document to disk"));
    connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));

    saveAsAct = new QAction(tr("Save &As..."), this);
    saveAsAct->setStatusTip(tr("Save the document under a new name"));
    connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));

    exitAct = new QAction(tr("E&xit"), this);
    exitAct->setShortcut(tr("Ctrl+Q"));
    exitAct->setStatusTip(tr("Exit the application"));
    connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));

    cutAct = new QAction(QIcon(":/images/images/cut.png"), tr("Cu&t"), this);
    cutAct->setShortcut(tr("Ctrl+X"));
    cutAct->setStatusTip(tr("Cut the current selection's contents to the "
                            "clipboard"));
    connect(cutAct, SIGNAL(triggered()), textEdit, SLOT(cut()));

    copyAct = new QAction(QIcon(":/images/images/copy.png"), tr("&Copy"), this);
    copyAct->setShortcut(tr("Ctrl+C"));
    copyAct->setStatusTip(tr("Copy the current selection's contents to the "
                             "clipboard"));
    connect(copyAct, SIGNAL(triggered()), textEdit, SLOT(copy()));

    pasteAct = new QAction(QIcon(":/images/images/paste.png"), tr("&Paste"), this);
    pasteAct->setShortcut(tr("Ctrl+V"));
    pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current "
                              "selection"));
    connect(pasteAct, SIGNAL(triggered()), textEdit, SLOT(paste()));

    aboutAct = new QAction(tr("&About"), this);
    aboutAct->setStatusTip(tr("Show the application's About box"));
    connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));

    aboutQtAct = new QAction(tr("About &Qt"), this);
    aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
    connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));

    cutAct->setEnabled(false);
    copyAct->setEnabled(false);
    connect(textEdit, SIGNAL(copyAvailable(bool)),
            cutAct, SLOT(setEnabled(bool)));
    connect(textEdit, SIGNAL(copyAvailable(bool)),
            copyAct, SLOT(setEnabled(bool)));
}

void MainWindow::createMenus()
{
    fileMenu = menuBar()->addMenu(tr("&File"));
    fileMenu->addAction(newAct);
    fileMenu->addAction(openAct);
    fileMenu->addAction(saveAct);
    fileMenu->addAction(saveAsAct);
    fileMenu->addSeparator();
    fileMenu->addAction(exitAct);

    editMenu = menuBar()->addMenu(tr("&Edit"));
    editMenu->addAction(cutAct);
    editMenu->addAction(copyAct);
    editMenu->addAction(pasteAct);

    menuBar()->addSeparator();

    helpMenu = menuBar()->addMenu(tr("&Help"));
    helpMenu->addAction(aboutAct);
    helpMenu->addAction(aboutQtAct);
}

void MainWindow::createToolBars()
{
    fileToolBar = addToolBar(tr("File"));
    fileToolBar->addAction(newAct);
    fileToolBar->addAction(openAct);
    fileToolBar->addAction(saveAct);

    editToolBar = addToolBar(tr("Edit"));
    editToolBar->addAction(cutAct);
    editToolBar->addAction(copyAct);
    editToolBar->addAction(pasteAct);
}

void MainWindow::createStatusBar()
{
    statusBar()->showMessage(tr("Ready"));
}

void MainWindow::readSettings()
{
    QSettings settings("Trolltech", "Application Example");
    QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
    QSize size = settings.value("size", QSize(400, 400)).toSize();
    resize(size);
    move(pos);
}

void MainWindow::writeSettings()
{
    QSettings settings("Trolltech", "Application Example");
    settings.setValue("pos", pos());
    settings.setValue("size", size());
}

bool MainWindow::maybeSave()
{
    if (textEdit->isModified()) {
        int ret = QMessageBox::warning(this, tr("Application"),
                                       tr("The document has been modified.\n"
                                          "Do you want to save your changes?"),
                                       QMessageBox::Yes | QMessageBox::Default,
                                       QMessageBox::No,
                                       QMessageBox::Cancel | QMessageBox::Escape);
        if (ret == QMessageBox::Yes)
            return save();
        else if (ret == QMessageBox::Cancel)
            return false;
    }
    return true;
}

void MainWindow::loadFile(const QString &fileName)
{
    QFile file(fileName);
    if (!file.open(QFile::ReadOnly)) {
        QMessageBox::warning(this, tr("Application"),
                             tr("Cannot read file %1:\n%2.")
                                 .arg(fileName)
                                 .arg(file.errorString()));
        return;
    }

    QTextStream in(&file);
    QApplication::setOverrideCursor(Qt::WaitCursor);
    textEdit->setText(in.readAll());
    QApplication::restoreOverrideCursor();

    setCurrentFile(fileName);
    statusBar()->showMessage(tr("File loaded"), 2000);
}

bool MainWindow::saveFile(const QString &fileName)
{
    QFile file(fileName);
    if (!file.open(QFile::WriteOnly)) {
        QMessageBox::warning(this, tr("Application"),
                             tr("Cannot write file %1:\n%2.")
                                 .arg(fileName)
                                 .arg(file.errorString()));
        return false;
    }

    QTextStream out(&file);
    QApplication::setOverrideCursor(Qt::WaitCursor);
    out << textEdit->text();
    QApplication::restoreOverrideCursor();

    setCurrentFile(fileName);
    statusBar()->showMessage(tr("File saved"), 2000);
    return true;
}

void MainWindow::setCurrentFile(const QString &fileName)
{
    curFile = fileName;
    textEdit->setModified(false);
    setWindowModified(false);

    QString shownName;
    if (curFile.isEmpty())
        shownName = "untitled.txt";
    else
        shownName = strippedName(curFile);

    setWindowTitle(tr("%1[*] - %2").arg(shownName).arg(tr("Application")));
}

QString MainWindow::strippedName(const QString &fullFileName)
{
    return QFileInfo(fullFileName).fileName();
}

 

8、构建程序,运行程序,效果如下:

 

标签:void,tr,编辑器,textEdit,QScintilla,SQL,include,MainWindow
From: https://www.cnblogs.com/lavezhang/p/18000322

相关文章

  • MySQL 期末总结
    MYSQL一、对表结构进行操作1.主键1)添加主键--1.主键/* 方式一:创建表的时候在字段后面+primarykey 方式二:写完字段之后在指定主键,创建标的字段下面 [constraint<约束名>]primarykey*/usemydb1;createtableemp1( eidint, enamevarchar(20), d......
  • [word] word 2016没有公式编辑器吗
    word2016有公式编辑器。找到word2016里面自带的编辑器,插入–对象–找到MAthtapy3.0公式-确定就可以啦这样我们就可以对我们需要输入的公式进行编辑了,如果输入两个接连的公式,可以按一下空格键。......
  • seatunnel-2.3.3测试excel入库mysql
    1.背景客户需要excel导入功能,同时支持导入多种数据源,尝试用seatunnel数据集成工具来实现。2.步骤2.1配置文件./config/v2.excel2mysql.configenv{#YoucansetSeaTunnelenvironmentconfigurationhereexecution.parallelism=1job.mode="BATCH"}source......
  • 数据库MySQL8.0.29安装与备份||了解和掌握MySQL的安装和简单使用和备份数据
    内容:了解和掌握MySQL的安装和简单使用:(1) 了解安装MySQL的软硬件环境和安装方法;(2) 熟悉MySQL的相关基本使用;(3) 熟悉MySQL的构成和相关工具;(4) 通过MySQL的使用来理解数据库系统的基本概念。要求:1. 在微机上安装MySQL数据库系统,为后续实验搭建实验环境,提供前期准备;2. 完成实......
  • Mysql中索引的描述设计
    Mysql中索引的描述设计1,索引是占用存储空间的2,my_myisam.myi和account.ibd存放索引3,查询效率提高,增删改效率降低;索引表以查询为主索引结构 二叉树结构一个根节点下只能有两个节点,当子节点比根节点小在左侧,当比根节点大在二叉树右侧缺点:大数据量时,检索慢,如果都比根节点小会......
  • SQL Server MERGE(合并)语句
    来源 https://www.cnblogs.com/yigegaozhongsheng/p/11941734.html如何使用SQLServerMERGE语句基于与另一个表匹配的值来更新表中的数据。  SQLServer MERGE语句 假设有两个表,分别称为源表和目标表,并且需要根据与源表匹配的值来更新目标表。有以下三种情况: 源表......
  • 使用 PyQt5(PySide2)+SQLAlchemy 做一个登录注册页(一)
    使用PyQt5(PySide2)+SQLAlchemy做一个登录注册页(一)本文将介绍自己用PyQt5+SQLAlchemy做的一个登录注册页,使用邮箱接收验证码,本文介绍是前后端未分离的实现方式,后续将出一个前后端分离的,你可以将PyQt5改为PySide2以获得更宽松的开源协议本文由于涉及到的代码较多,将会是......
  • golang 正则过滤sql注入的方法
    该方法返回的是一个bool值packagemainimport"regexp"import"fmt"//正则过滤sql注入的方法//参数:要匹配的语句funcFilteredSQLInject(to_match_strstring)bool{//过滤‘//ORACLE注解--/**///关键字过滤update,delete//正则的字符......
  • MySQL介绍
    数据库的由来和基本概念什么是数据库?|Oracle中国【一】数据的发展史早期未出现互联网前,每个人都只可以在本地存储,且存储的数据格式都是根据每个人的需要自由定义的出现网络后,可以在局域网内进行多台计算机的数据共享,而这时,数据的格式只能由人为约束,约定俗成好一套数据存......
  • Mysql中存储引擎InnoDB,MyISAM,MEMORY比较
    Mysql中存储引擎InnoDB,MyISAM,MEMORY比较showENGINES--查看数据库支持的搜索引擎ENGINE=InnoDB--使用的InnoDB引擎CREATETABLE`user1`(`id`bigint(20)NOTNULLDEFAULT'0',`name`varchar(255)DEFAULTNULL,`age`int(11)DEFAULTNULL,`sex`varchar(255)......