溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Qt怎么實(shí)現(xiàn)自動(dòng)清理早期數(shù)據(jù)功能

發(fā)布時(shí)間:2022-07-12 09:44:09 來源:億速云 閱讀:222 作者:iii 欄目:開發(fā)技術(shù)

今天小編給大家分享一下Qt怎么實(shí)現(xiàn)自動(dòng)清理早期數(shù)據(jù)功能的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

    功能特點(diǎn)

    1 軟件模塊

    設(shè)備監(jiān)控模塊,包括數(shù)據(jù)監(jiān)控(表格形式展示)、設(shè)備面板(面板形式展示)、地圖監(jiān)控(地圖形式展示)、曲線監(jiān)控(曲線形式展示)。

    數(shù)據(jù)查詢模塊,包括報(bào)警記錄、運(yùn)行記錄、操作記錄。

    系統(tǒng)設(shè)置模塊,包括基本設(shè)置、端口管理、控制器管理、探測(cè)器管理、報(bào)警聯(lián)動(dòng)、類型設(shè)置等。

    其他設(shè)置模塊,包括用戶管理、地圖管理、位置調(diào)整、組態(tài)設(shè)計(jì)、設(shè)備調(diào)試等。

    2 基礎(chǔ)功能

    1. 設(shè)備數(shù)據(jù)采集,支持串口、網(wǎng)絡(luò),串口可設(shè)置串口號(hào)、波特率,網(wǎng)絡(luò)可設(shè)置IP地址、通訊端口。

    2. 每個(gè)端口支持采集周期時(shí)間,默認(rèn)1秒鐘一個(gè)設(shè)備。

    3. 支持設(shè)置通訊超時(shí)次數(shù),默認(rèn)3次。

    4. 支持最大重連時(shí)間,用于重新讀取離線的設(shè)備。

    5. 控制器信息,能夠添加控制器名稱,選擇控制器地址、控制器型號(hào),設(shè)置該控制器下面的探測(cè)器數(shù)量。

    6. 探測(cè)器信息,能夠添加位號(hào)、探測(cè)器型號(hào)、氣體種類、氣體符號(hào)、高報(bào)值、低報(bào)值、緩沖值、清零值、是否啟用、報(bào)警聲音、背景地圖、存儲(chǔ)周期、數(shù)值換算小數(shù)點(diǎn)位數(shù)、報(bào)警延時(shí)時(shí)間、報(bào)警的類型(HH,LL,HL)等。

    7. 類型管理可配置控制器型號(hào)、探測(cè)器型號(hào)、氣體種類、氣體符號(hào)等。

    8. 地圖支持導(dǎo)入和刪除,所有的探測(cè)器在地圖上的位置可自由拖動(dòng)保存。

    9. 端口信息、控制器信息、探測(cè)器信息、類型信息、用戶信息等,都支持導(dǎo)入、導(dǎo)出、導(dǎo)出到excel、打印。

    10. 運(yùn)行記錄、報(bào)警記錄、操作記錄,都支持多條件組合查詢,比如時(shí)間段、控制器、探測(cè)器等,所有記錄支持導(dǎo)出到excel/pdf和打印。

    11. 運(yùn)行記錄、報(bào)警記錄、操作記錄都可刪除指定時(shí)間范圍內(nèi)的數(shù)據(jù)。

    12. 系統(tǒng)設(shè)置可選擇對(duì)應(yīng)表最大保存記錄數(shù),自動(dòng)清理早期數(shù)據(jù),留出足夠的空間存儲(chǔ)重要的數(shù)據(jù)。

    13. 報(bào)警短信轉(zhuǎn)發(fā),支持多個(gè)接收手機(jī)號(hào)碼,可設(shè)定發(fā)送間隔,比如即時(shí)發(fā)送或者6個(gè)小時(shí)發(fā)送一次所有的報(bào)警信息,短信內(nèi)容過長,自動(dòng)拆分多條短信。

    14. 報(bào)警郵件轉(zhuǎn)發(fā),支持多個(gè)接收郵箱,可設(shè)定發(fā)送間隔,比如即時(shí)發(fā)送或者6個(gè)小時(shí)發(fā)送一次所有的報(bào)警信息,支持附件發(fā)送。

    15. 設(shè)置軟件的中文標(biāo)題、英文標(biāo)題、logo路徑、版權(quán)所有等。

    16. 開關(guān)設(shè)置開機(jī)運(yùn)行、報(bào)警聲音、自動(dòng)登錄、記住密碼等。

    17. 報(bào)警聲音可設(shè)置播放次數(shù),界面風(fēng)格樣式提供18套皮膚文件選擇。

    18. 用戶管理,包括用戶權(quán)限配置,不同用戶可以有不同模塊的權(quán)限。

    19. 用戶登錄和用戶退出,可以記住密碼和自動(dòng)登錄,超過三次報(bào)錯(cuò)提示并關(guān)閉程序。

    20. 四種監(jiān)控模式,設(shè)備面板監(jiān)控、地圖監(jiān)控、表格數(shù)據(jù)監(jiān)控、曲線數(shù)據(jù)監(jiān)控,可自由切換,四種模式下都實(shí)時(shí)展示采集到的數(shù)據(jù),報(bào)警閃爍等。

    21. 報(bào)警繼電器聯(lián)動(dòng),一個(gè)位號(hào)可以跨串口聯(lián)動(dòng)多個(gè)模塊和繼電器號(hào),支持多對(duì)多。

    3 特色功能

    1. 通信協(xié)議支持modbus_com、modbus_tcp_rtu,后期拓展mqtt等協(xié)議。

    2. 數(shù)據(jù)源除了真實(shí)的硬件設(shè)備采集,還可選數(shù)據(jù)庫采集,這樣用戶可以安排其他程序員比如java程序員將前端采集好的數(shù)據(jù)放到數(shù)據(jù)庫,本系統(tǒng)直接從數(shù)據(jù)庫采集即可。數(shù)據(jù)庫采集模式可以作為通用的系統(tǒng)使用,更適合多人多系統(tǒng)協(xié)作。

    3. 智能跳過超時(shí)的設(shè)備,加快對(duì)在線設(shè)備的采集速度,當(dāng)設(shè)備數(shù)量很多的時(shí)候尤其有用。

    4. 對(duì)智能跳過的超時(shí)的設(shè)備,在設(shè)定的重連時(shí)間自動(dòng)采集一次,以便探測(cè)設(shè)備是否又重新上線。

    5. 每個(gè)探測(cè)器可控是否啟用,不啟用則不會(huì)采集,也不會(huì)在界面顯示,相當(dāng)于運(yùn)行階段臨時(shí)關(guān)閉。

    6. 探測(cè)器可設(shè)置緩沖值和報(bào)警延時(shí)時(shí)間,在該值附近波動(dòng)產(chǎn)生的報(bào)警,不計(jì)入報(bào)警,只有持續(xù)處于報(bào)警值且超過報(bào)警延時(shí)時(shí)間才算真正報(bào)警,這樣可以規(guī)避很多波動(dòng)導(dǎo)致的誤報(bào)。

    7. 探測(cè)器可設(shè)置存儲(chǔ)周期,按照設(shè)定的時(shí)間來存儲(chǔ)一條運(yùn)行記錄,可以按照重要程度對(duì)重要性高的設(shè)定存儲(chǔ)周期短一些,不重要的設(shè)定大一些,這樣可以節(jié)省不少的存儲(chǔ)空間,也保證了重要的數(shù)據(jù)及時(shí)存儲(chǔ)。

    8. 探測(cè)器可設(shè)置清零值,在一些高精度高靈敏的設(shè)備可能出廠的時(shí)候默認(rèn)值未必是0,需要設(shè)定清零值來表示初始值。

    9. 探測(cè)器可設(shè)置小數(shù)點(diǎn),用于計(jì)算后的真實(shí)數(shù)據(jù)控制小數(shù)點(diǎn)點(diǎn)位顯示,相當(dāng)于除以10、除以100、除以1000,這樣大部分的探測(cè)器數(shù)據(jù)直接通過小數(shù)點(diǎn)位設(shè)置控制真實(shí)換算后的值,極個(gè)別的需要特殊轉(zhuǎn)換的可以在通信協(xié)議中約定。

    10. 探測(cè)器報(bào)警的類型支持多種,有些設(shè)備是高于某個(gè)值高報(bào),低于某個(gè)值低報(bào),而有些設(shè)備是在最小值最大值范圍內(nèi)是高報(bào),低于最小值低報(bào),高于最大值正常。這樣可以分情況處理,涵蓋各種報(bào)警類型。

    11. 原創(chuàng)數(shù)據(jù)導(dǎo)入、導(dǎo)出、打印機(jī)制,跨平臺(tái)不依賴任何組件,瞬間導(dǎo)出數(shù)據(jù)。

    12. 導(dǎo)出到excel的記錄支持所有excel、wps等表格文件版本,不依賴excel等軟件。

    13. 高報(bào)顏色、低報(bào)顏色、正常顏色、默認(rèn)值顏色等,都可以自由設(shè)置。

    14. 支持云端數(shù)據(jù)同步,將本地采集到的數(shù)據(jù)實(shí)時(shí)同步到云端。

    15. 支持網(wǎng)絡(luò)轉(zhuǎn)發(fā)和網(wǎng)絡(luò)接收,網(wǎng)絡(luò)接收開啟后,軟件從udp接收數(shù)據(jù)進(jìn)行解析。網(wǎng)絡(luò)轉(zhuǎn)發(fā)支持多個(gè)目標(biāo)IP,這樣就實(shí)現(xiàn)了本地采集的軟件,自由將數(shù)據(jù)轉(zhuǎn)到客戶端,隨時(shí)查看采集到的數(shù)據(jù)。

    16. 自動(dòng)記住用戶最后停留的界面以及其他配置信息,重啟后自動(dòng)應(yīng)用。

    17. 報(bào)警自動(dòng)切換到對(duì)應(yīng)的地圖,探測(cè)器按鈕閃爍,表格數(shù)據(jù)對(duì)應(yīng)顏色顯示。

    18. 雙擊探測(cè)器圖標(biāo),彈出對(duì)應(yīng)探測(cè)器詳細(xì)信息,可以根據(jù)需要定制回控操作。

    19. 數(shù)據(jù)庫支持多種,包括sqlite、mysql、sqlserver、postgresql、oracle、人大金倉等。

    20. 本地設(shè)備采集到的數(shù)據(jù)實(shí)時(shí)上傳到云端,以便手機(jī)APP或者web等其他方式提取。

    21. 自帶設(shè)備模擬工具,支持不同型號(hào)的多個(gè)設(shè)備數(shù)據(jù)模擬,同時(shí)還帶數(shù)據(jù)庫數(shù)據(jù)模擬,以便在沒有設(shè)備的時(shí)候測(cè)試數(shù)據(jù)。

    22. 標(biāo)準(zhǔn)modbus協(xié)議,各種控制器類型、探測(cè)器類型、種類、符號(hào)等全部自定義,非常靈活和強(qiáng)大,通信協(xié)議示例數(shù)據(jù)非常完整,通用各種modbus協(xié)議系統(tǒng),適用于各種應(yīng)用場(chǎng)景接入。

    23. 同時(shí)集成了串口通信、網(wǎng)絡(luò)通信、數(shù)據(jù)庫通信、數(shù)據(jù)導(dǎo)入導(dǎo)出打印、通信協(xié)議解析、界面UI、全局換膚等眾多組件和知識(shí)點(diǎn),非常適合新手入門和進(jìn)階。

    24. 支持xp、win7、win10、、win11、linux、mac、各種國產(chǎn)系統(tǒng)(UOS、中標(biāo)麒麟、銀河麒麟等)、嵌入式linux等系統(tǒng)。

    25. 注釋完整,項(xiàng)目結(jié)構(gòu)清晰,超級(jí)詳細(xì)完整的使用開發(fā)手冊(cè),精確到每個(gè)代碼文件的功能說明,不斷持續(xù)迭代版本。

    效果圖

    Qt怎么實(shí)現(xiàn)自動(dòng)清理早期數(shù)據(jù)功能

    Qt怎么實(shí)現(xiàn)自動(dòng)清理早期數(shù)據(jù)功能

    五、相關(guān)代碼

    int DbCleanThread::getCount()
    {
        int count = -1;
        if (!dbOk) {
            return count;
        }
    
        time.restart();
        QString sql = QString("select count(%1) from %2").arg(countName).arg(tableName);
        QSqlQuery query(database);
        if (query.exec(sql)) {
            if (query.next()) {
                count = query.value(0).toInt();
                QString msg = QString("(共 %1 條/用時(shí) %2 秒)").arg(count).arg(getUseTime());
                emit debug(QString("%1數(shù)據(jù)庫獲取記錄行數(shù)%2").arg(dbFlag).arg(msg));
                emit receiveCount(tableName, count, time.elapsed());
            }
        }
    
        return count;
    }
    
    QStringList DbCleanThread::getCleanValue(int cleanCount)
    {
        QStringList list;
        if (!dbOk) {
            return list;
        }
    
        QSqlQuery query(database);
        query.setForwardOnly(true);
        QString sql = DbHelper::getSelectCountSql(dbType, tableName, whereColumnName, "", orderSql, cleanCount);
        if (query.exec(sql)) {
            while (query.next()) {
                list << query.value(0).toString();
            }
        }
    
        return list;
    }
    
    void DbCleanThread::cleanData()
    {
        if (!dbOk) {
            return;
        }
    
        //首先查找總記錄數(shù),如果總記錄數(shù)超過限制,則將超出的部分按照字段排序進(jìn)行刪除
        int count = getCount();
        int cleanCount = (count - maxCount);
        if (cleanCount < 100) {
            return;
        }
    
        time.restart();
    
        //每次最大清理1000條數(shù)據(jù)
        cleanCount = cleanCount > 1000 ? 1000 : cleanCount;
        //將要?jiǎng)h除的數(shù)據(jù)指定字段集合查詢出來
        QStringList list = getCleanValue(cleanCount);
        if (list.count() == 0) {
            return;
        }
    
        //刪除數(shù)據(jù)
        QSqlQuery query(database);
        QString sql = QString("delete from %1 where %2 in(%3)").arg(tableName).arg(whereColumnName).arg(list.join(","));
        dbOk = query.exec(sql);
        //qDebug() << TIMEMS << sql;
    
        QString msg = QString("(共 %1 條/用時(shí) %2 秒)").arg(cleanCount).arg(getUseTime());
        if (dbOk) {
            emit debug(QString("%1數(shù)據(jù)庫清理數(shù)據(jù)成功%2").arg(dbFlag).arg(msg));
        } else {
            QString text = database.lastError().text();
            emit error(QString("%1數(shù)據(jù)庫清理數(shù)據(jù)失敗%2, 原因: %3").arg(dbFlag).arg(msg).arg(text));
            qDebug() << TIMEMS << this->objectName() << text;
        }
    }
    
    void DbCleanThread::cleanPath()
    {
        if (dirPath.isEmpty()) {
            return;
        }
    
        //找出該文件夾下的所有文件夾
        QDir dir(dirPath);
        if (!dir.exists()) {
            return;
        }
    
        //按照目錄查找,過濾文件夾,按照文件名稱排序
        dir.setFilter(QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot);
        dir.setSorting(QDir::Name);
        QStringList list = dir.entryList();
    
        //遍歷所有目錄,對(duì)所有文件大小相加得到總大小,文件就在文件夾下,不會(huì)再有子目錄
        qint64 size = 0;
        foreach (QString path, list) {
            QDir d(dirPath + "/" + path);
            QFileInfoList infos = d.entryInfoList(dirFileFilter);
            foreach (QFileInfo info, infos) {
                size += info.size();
            }
    
            //轉(zhuǎn)化成MB,超過預(yù)定大小自動(dòng)刪除第一個(gè)文件夾,跳出循環(huán)無需繼續(xù)判斷
            int sizeMB = size / (1024 * 1024);
            if (sizeMB >= dirMaxSize) {
                //刪除該目錄下的所有文件
                QString path = dirPath + "/" + list.at(0);
                QDir dir(path);
                dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
                QStringList files = dir.entryList();
                foreach (QString file, files) {
                    dir.remove(file);
                    qDebug() << TIMEMS << "刪除文件" << path << file;
                }
    
                //刪除文件夾本身
                dir.rmdir(path);
                QString msg = QString("(共 %1 個(gè)文件/用時(shí) %2 秒)").arg(files.count()).arg(getUseTime());
                emit debug(QString("%1數(shù)據(jù)庫自動(dòng)清理目錄成功%2").arg(dbFlag).arg(msg));
                break;
            }
        }
    }
    
    void DbCleanThread::deletePath(const QString &path)
    {
        QDir dir(path);
    #if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
        //這個(gè)方法可以遞歸徹底刪除文件夾 不管文件夾下是否有文件 比較暴力
        //此方法慎用 必須指定明確的文件夾 不然刪除默認(rèn)的目錄哭都來不及 網(wǎng)上多個(gè)人中招
        dir.removeRecursively();
    #else
        //循環(huán)遍歷刪除文件及文件夾
        dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
        QFileInfoList fileList = dir.entryInfoList();
        foreach (QFileInfo fi, fileList) {
            if (fi.isFile()) {
                fi.dir().remove(fi.fileName());
            } else {
                deletePath(fi.absoluteFilePath());
                dir.rmpath(fi.absoluteFilePath());
            }
        }
        //最后刪除最外層的目錄
        dir.rmpath(path);
    #endif
    }

    以上就是“Qt怎么實(shí)現(xiàn)自動(dòng)清理早期數(shù)據(jù)功能”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    qt
    AI