Qt Qml服务器使用热加载处理时的问题

在使用Qt Qml编写某一个服务器时,使用之前的热加载便于在Sql报错时输出哪些地方出了问题并可以排查,主要在重载Server时Sql initdb这里会警告提示,提示代码如下

QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.

貌似对查询结果没有影响,当使用类似于QSqlDatabase::removeDatabase("qt_sql_default_connection"); 可以消除第二个警告,无法消除第一个警告,不知道为啥。

其中,sql处理类的初始化这里

QSqlError DatabaseManager::initdb()
{
    //           QSqlDatabase::removeDatabase("qt_sql_default_connection");
     // 可以在重载Server时消除警告QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.

    db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");
    db.setPort(xxx);
    db.setUserName("xx");
    db.setPassword("xxx");
    db.setDatabaseName("xxx");
    if(!db.open())
    {
        return db.lastError();
    }
    emit connectedSql();
}

用于调试的代码如下:

QSqlError DatabaseManager::myExec(QString data)
{
    QSqlQuery query(db);
    query.exec(data);
     bool isExec = query.exec();
     if(isExec)
     {
         qDebug() << "Result: ";
         while (query.next()) {
             QString d = "----";
             QSqlRecord q = query.record();
             for(int i = 0;i < q.count();++i)
             {
                 d += q.value(i).toString() + " ";
             }
             qDebug() << d;
         }
         qDebug() << "End";
         return QSqlError();
     }
     qDebug() << "Data Error: " << query.lastError() << query.lastQuery();
     return query.lastError();
}

使用热加载的组件LdLoader,qml如下

import QtQuick 2.0
import cpp 1.0
import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.12

Item {
    id: control
    anchors.fill: parent
    property string source
    property var loader: loader

    DropArea
    {
        id: dropArea
        anchors.fill: parent
        onEntered:
        {
            if(drag.hasText)
            {
                console.log(drag.text)
                   loader.source = drag.text + "?v=" + new Date().getTime()
            }
        }
        onExited:
        {
        }
    }
    RowLayout
          {
              Layout.preferredHeight: parent.height
              Layout.preferredWidth: parent.width
              Loader
              {
                  id:loader
                  Layout.preferredWidth: parent.width
                  Layout.preferredHeight: parent.height
                  onStatusChanged:
                  {
//                      if(status === Loader.Error)
//                      {
//                          MathUtil.trace(status)
//                      }
//                      else if(status === Loader.Loading)
//                      {
//                          sourceComponent = waitCom
//                      }
                  }
              }
          }

    FileWatcher
    {
        id: fileWatcher
        pathWatched:  loader.source
        onPathWatchedChanged:
        {
            console.log(path)
            loader.source = ""
            loader.source = "file://" + path + "?v=" + new Date().getTime().toString() 
        }
    }

}

在主窗口中main.qml可以调用 LdLoader.qml和TestServer.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import cpp 1.0

Window {
    id: window
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    LdLoader
    {
        id: ldLoader
        anchors.fill: parent
        Component.onCompleted:
        {
            ldLoader.loader.source = "file:///home/.../TestServer.qml" + "?v=" + new Date().getTime()
        }
    }

}

TestServer.qml部分代码如下

import QtQuick 2.0
import cpp 1.0
import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.12
Item {
    anchors.fill: parent
    Connections{
        target: server
        onConnectedSql:{
              server.runSql("select * from user")
        }
    }
LdServer
    {
        id: server

        Component.onCompleted:
        {
            server.startServer(portTextField.text)
        }
        Component.onDestruction:
        {
            server.stopServer()
        }
    }

}

LdServer.cpp的部分代码如下:

namespace ld {

// 服务器端
class Server : public QObject
{
    Q_OBJECT
public:
    Server(QObject* p = nullptr);
    ~Server();
    Q_INVOKABLE void startServer(uint32_t port= 12345)
    {
        if(dbManager==NULL)
        {
            dbManager = new ld::DatabaseManager(this);
            connect(dbManager, &DatabaseManager::connectedSql, this, &Server::connectedSql);
            dbManager->initdb();
        }
        if(server == NULL)
        {
            server = new QWebSocketServer("MyWebSocketServer", QWebSocketServer::NonSecureMode, this);
            connect(server, &QWebSocketServer::newConnection, this, &Server::onNewConnection);
            server->listen(QHostAddress::Any, port);
        }
    };
    Q_INVOKABLE void stopServer();
    Q_INVOKABLE void runSql(QString data){
        if(dbManager && dbManager->db.isOpen())
        {
            dbManager->myExec(data);
        }
        if(dbManager && !dbManager->db.isOpen())
        {
            dbManager->initdb();
            dbManager->myExec(data);
        }
    }
public slots:
    void onNewConnection()
    {

    socket = server->nextPendingConnection();
   ...
    connect(socket, &QWebSocket::textMessageReceived, this, &Server::onTextMessageReceived);
    connect(socket, &QWebSocket::disconnected, this, &Server::onDisconnect);
};
    void onTextMessageReceived(const QString &message);
    void onDisconnect() {
         QWebSocket* websocket = reinterpret_cast<QWebSocket*>(sender());
        if(websocket)
        {
            ...
            websocket->deleteLater();
        } };
signals:
    ...
    void connectedSql();
private:
    QWebSocketServer *server= NULL;
    QTimer *timer= NULL;
    QWebSocket *socket= NULL;
    ld::DatabaseManager *dbManager = NULL;
    QList<QWebSocket *> socketlist;
    ...
}
}

运行程序并修改TestServer.qml 里的数据时还是报第一个错误,但是可以查询到sql里的数据以及报错信息。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值