Qt/C++编程之SQL数据库管理器简单实例(SQL Explorer资源管理器),可同时管理多台SQL数据库服务器

实例功能

不带参数启动的界面,会自动弹出连接对话框,输入正确的参数连接数据库
Qt/C++编程之SQL数据库管理器简单实例(SQL Explorer资源管理器),可同时管理多台SQL数据库服务器_第1张图片
带参数启动,会根据参数自动连接多台服务器,双击服务器中的数据库表,右边会显示表格内容,在表格内容区点鼠标右键,可以对数据库表进行添加、删除等操作;右键点击数据库,选择【showMetaData】,会在右边显示数据表的结构(名称、类型、长度等信息),可以在下面的【SQL Query】中直接输入sql语句,直接对数据库进行查询、添加、删除、修改等操作,实例同时连接两台不同IP地址的服务器
Qt/C++编程之SQL数据库管理器简单实例(SQL Explorer资源管理器),可同时管理多台SQL数据库服务器_第2张图片
带参数启动参考如下命令,sqlbrowser是实例程序名称,后面跟两个SQL连接字符串(字符串之间有一个空格),QODBC是驱动名称,hotelDSN是ODBC中创建的数据源

sqlbrowser QODBC://user:[email protected]/hotelDSN QODBC://user:[email protected]/aidel

在ODBC中创建的数据源:在【运行】中打开odbcad32,界面如下
Qt/C++编程之SQL数据库管理器简单实例(SQL Explorer资源管理器),可同时管理多台SQL数据库服务器_第3张图片

实例简介:

大部份的代码都有注释,直接上代码

  • main.cpp主函数代码
#include 
#include 
#include 
#include "browser.h"

void addConnectionsFromCommandline(const QStringList &args, Browser *browser)
{
   
    for (int i = 1; i < args.count(); ++i) {
   
        /* TolerantMode:QUrl将尝试纠正一些常见的网址错误,这种模式对于解析来自不严格符合标准的来源的网址很有用
         * */
        QUrl url(args.at(i), QUrl::TolerantMode);
        /* 如果URL非空且有效,则返回真;否则返回false
         * */
        if (!url.isValid()) {
   
            /*  qPrintable(args.at(i))以常量字符指针形式返回字符串,这相当于str.toLocal8Bit().constData()。
             */
            qWarning("Invalid URL: %s", qPrintable(args.at(i)));
            continue;
        }
        /* ftp地址实例 ftp://tray:[email protected]/pub/somethine:2021
         * ftp                               为scheme,以小写形式返回
         * tray                              为user
         * 5uQQo_f                           为password
         * ftp.example.com                   为host
         * 2021                              为port
         * tray:5uQQo_f                      为user info
         * tray:[email protected]:2021 为authority
         * /pub/somethine/                   为path
         *
         * https://doc.qt.io/qt-5/qurl.html#isValid
         * isValid 为fragment,fragment(片断)由“#”后跟一串字符表示
         *
         * 对于邮件地址 mailto:[email protected]
         * [email protected]为path
         *
         * 调用isRelative()将返回该网址是否是相对的,相对URL没有scheme。例如:
         *   qDebug() << QUrl("main.qml").isRelative();          // true: no scheme
             qDebug() << QUrl("qml/main.qml").isRelative();      // true: no scheme
             qDebug() << QUrl("file:main.qml").isRelative();     // false: has "file" scheme
             qDebug() << QUrl("file:qml/main.qml").isRelative(); // false: has "file" scheme
         *
         * QUrl url("http://qt-project.org/support/file.html");
           // url.adjusted(RemoveFilename) == "http://qt-project.org/support/"
           // url.fileName() == "file.html"

         * url.path().mid(1)返回url中path除第1个字符外的所有字符
         * 原型 QString QString::mid(int position, int n = -1) const
         * 从指定的位置索引position开始,返回一个包含n个字符的字符串
         * 如果n为-1(默认值),该函数返回指定位置position后的所有可用字符
         *  QString x = "Nine pineapples";
            QString y = x.mid(5, 4);            // y == "pine"
            QString z = x.mid(5);               // z == "pineapples"

         * url.port(-1))返回网址的端口,如果端口未指定或者-1,则返回默认端口
         * */
        QSqlError err = browser->addConnection(url.scheme().toUpper(), url.path().mid(1), url.host(),
                                               url.userName(), url.password(), url.port(-1));
        if (err.type() != QSqlError::NoError)
            qDebug() << "Unable to open connection:" << err;
    }
}

int main(int argc, char *argv[])
{
   
    QApplication app(argc, argv);

    QMainWindow mainWin;
    mainWin.setWindowTitle(QObject::tr("Qt SQL Browser"));

    Browser browser(&mainWin);
    mainWin.setCentralWidget(&browser);

    QMenu *fileMenu = mainWin.menuBar()->addMenu(QObject::tr("&File"));
    fileMenu->addAction(QObject::tr("Add &Connection..."),
            [&]() {
    browser.addConnection(); });
    fileMenu->addSeparator();
    fileMenu->addAction(QObject::tr("&Quit"), []() {
    qApp->quit(); });

    QMenu *helpMenu = mainWin.menuBar()->addMenu(QObject::tr("&Help"));
    helpMenu->addAction(QObject::tr("About"), [&]() {
    browser.about(); });
    helpMenu->addAction(QObject::tr("About Qt"), []() {
    qApp->aboutQt(); });

    QObject::connect(&browser, &Browser::statusMessage, [&mainWin](const QString &text) {
   
        mainWin.statusBar()->showMessage(text);});
    //sqlbrowser QODBC://user:[email protected]/hotelDSN QODBC://user:[email protected]/aidel
    addConnectionsFromCommandline(app.arguments(), &browser);
    mainWin.show();
    // QSqlDatabase::connectionNames()返回包含所有连接名称的列表
    if (QSqlDatabase::connectionNames().isEmpty())
        /* 调用browser对象无参的信号或槽名addConnection(),如果可以调用该成员,则返回true。如果没有这样的成员或参数不匹配,则返回false
         * 如果类型是Qt::DirectConnection,将立即调用addConnection()
         * 如果类型是Qt::QueuedConnection,那么一旦应用程序进入主事件循环,就会发送QEvent,并调用addConnection()
         * 如果类型是Qt::BlockingQueuedConnection,则调用方法的方式与调用Qt::QueuedConnection的方式相同,只是当前线程将一直阻塞,直到事件被传递。
         * 使用这种连接类型在同一线程中的对象之间进行通信将导致死锁
         * 如果类型是Qt::AutoConnection,那么如果obj与调用者生活在同一个线程中,则同步调用成员;否则,它将异步调用该成员
         * 原型:
         * bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type,
         *                                QGenericReturnArgument ret,
         *                                QGenericArgument val0 = QGenericArgument(nullptr),
         *                                QGenericArgument val1 = QGenericArgument(),
         *                                QGenericArgument val2 = QGenericArgument(),
         *                                QGenericArgument val3 = QGenericArgument(),
         *                                QGenericArgument val4 = QGenericArgument(),
         *                                QGenericArgument val5 = QGenericArgument(),
         *                                QGenericArgument val6 = QGenericArgument(),
         *                                QGenericArgument val7 = QGenericArgument(),
         *                                QGenericArgument val8 = QGenericArgument(),
         *                                QGenericArgument val9 = QGenericArgument())
         * 成员函数调用的返回值放在ret中。
         * 如果调用是异步的,则无法计算返回值。您最多可以向成员函数传递十个参数(val0、val1、val2、val3、val4、val5、val6、val7、val8和val9)
         * QGenericArgument和QGenericReturnArgument是内部助手类。因为可以动态调用信号和槽,所以必须使用Q_ARG()和Q_RETURN_ARG()宏来封装参数。
         * Q_ARG()接受一个类型名和该类型的常量引用;Q_RETURN_ARG()采用一个类型名和一个非常数引用
         *
         * 要同步调用某个任意对象上的compute(QString,int,double)槽,如下:
           QString retVal;
           QMetaObject::invokeMethod(obj, "compute", Qt::DirectConnection,
                                    Q_RETURN_ARG(QString, retVal),
                                    Q_ARG(QString, "sqrt"),
                                    Q_ARG(int, 42),
                                    Q_ARG(double, 9.7));
         * */
        QMetaObject::invokeMethod(&browser, "addConnection", Qt::QueuedConnection);

    return app.exec();
}
  • browser.h主窗口的头文件代码
#ifndef BROWSER_H
#define BROWSER_H

#include 
#include 
#include "ui_browserwidget.h"

class ConnectionWidget;
QT_FORWARD_DECLARE_CLASS(QTableView)
QT_FORWARD_DECLARE_CLASS(QPushButton)
QT_FORWARD_DECLARE_CLASS(QTextEdit)
QT_FORWARD_DECLARE_CLASS(QSqlError)

class Browser: public QWidget, private Ui::Browser
{
   
    Q_OBJECT
public:
    Browser(QWidget *parent = nullptr);
    virtual ~Browser();

    QSqlError addConnection(const QString &driver, const QString &dbName, const QString &host,
                  const QString &user, const QString &passwd, int port = -1);

    void insertRow();
    void deleteRow();
    void updateActions();

public slots:
    void exec();
    void showTable(const QString &table);
    void showMetaData(const QString &table);
    void addConnection();
    void currentChanged() {
    updateActions(); }
    void about();

    void on_insertRowAction_triggered()
    {
    insertRow(); }
    void on_deleteRowAction_triggered()
    {
    deleteRow(); }
    void on_fieldStrategyAction_triggered();
    void on_rowStrategyAction_triggered();
    void on_manualStrategyAction_triggered();
    void on_submitAction_triggered();
    void on_revertAction_triggered();
    void on_selectAction_triggered();
    void on_connectionWidget_tableActivated(const QString &table)
    {
    showTable(<

你可能感兴趣的:(C++,与,Qt5,sql,qt,c++)