" />

最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Qt禁止程序多開(kāi)的實(shí)現(xiàn)示例

 更新時(shí)間:2023年09月03日 11:35:48   作者:貝勒里恩  
本文主要介紹了Qt 禁止程序多開(kāi)的實(shí)現(xiàn)示例,主要介紹了三種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、前言

Qt編寫(xiě)的程序,默認(rèn)是可以多開(kāi)的,但是有些時(shí)候,我們不希望程序可以同時(shí)打開(kāi)多個(gè),這時(shí)候就需要對(duì)程序的啟動(dòng)添加限制策略,阻止程序多開(kāi)。

二、常用的三種方法

1、使用共享內(nèi)存

原理:運(yùn)行主函數(shù)前線訪問(wèn)固定的共享內(nèi)存段,看看有沒(méi)有被使用。

  • 如果沒(méi)有使用該內(nèi)存段,就繼續(xù)運(yùn)行程序;
  • 如果使用了該內(nèi)存段,就報(bào)警并退出;

使用

  • 修改前
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}
  • 修改后
#include "widget.h"
#include <QApplication>
#include <QSharedMemory>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QSharedMemory shared_memory;            
    shared_memory.setKey(QString("666666"));//設(shè)置固定共享內(nèi)存段的key值
    if(shared_memory.attach())   //嘗試將進(jìn)程附加到該共享內(nèi)存段
    {
        return 0;   
    }
    if(shared_memory.create(1)) //創(chuàng)建1byte的共享內(nèi)存段
    {
        Widget w;
        w.show();
        return a.exec();
    }
    return 0;
}

2、使用QLocalServe

原理:創(chuàng)建一個(gè)本地服務(wù)器,并在程序啟動(dòng)的時(shí)候去連接服務(wù)器。

  • 如果連接上了,則說(shuō)明已有實(shí)例程序存在,退出;
  • 如果連接不上,則說(shuō)明沒(méi)有創(chuàng)建服務(wù)器,創(chuàng)建一個(gè)服務(wù)器,并正常運(yùn)行程序。

使用

    //連接LocalServer
    QString serverName = "localserver";
    QLocalSocket socket;
    socket.connectToServer(serverName);
    if(socket.waitForConnected(1000)) return(-1);
// 如果連接成功,說(shuō)明已經(jīng)存在指定的LocalServer,說(shuō)明已經(jīng)有應(yīng)用啟動(dòng)了,此時(shí)直接退出應(yīng)用即可
// 如果沒(méi)有指定的LocalServer存在,則connectToServer會(huì)返回錯(cuò)誤信息,此時(shí)創(chuàng)建LocalServer
    //創(chuàng)建LocalServer
    QLocalServer server;
    if (server.listen(serverName)) {
        // 此時(shí)監(jiān)聽(tīng)失敗,可能是程序崩潰時(shí),殘留進(jìn)程服務(wù)導(dǎo)致的,移除之
        if(server.serverError()== QAbstractSocket::AddressInUseError){
            QLocalServer::removeServer(serverName); 
            server.listen(serverName);
        }
    }

基于QLocalServer原理的定制類:

#ifndef SINGLEAPPLICATION_H
#define SINGLEAPPLICATION_H
#include <QObject>
#include <QApplication>
class QWidget;
class QLocalServer;
class SingleApplication : public QApplication
{
    Q_OBJECT
public:
    SingleApplication(int &argc, char **argv);
    bool isRunning();               // 是否已經(jīng)有實(shí)例在運(yùn)行
    QWidget *mainWindow;            // MainWindow指針
private slots:
    // 有新連接時(shí)觸發(fā)
    void newLocalConnection();
private:
    // 初始化本地連接
    void initLocalConnection();
    // 創(chuàng)建服務(wù)端
    void newLocalServer();
    bool bRunning;                  // 是否已經(jīng)有實(shí)例在運(yùn)行
    QLocalServer *localServer;      // 本地socket Server
    QString serverName;             // 服務(wù)名稱
};
#endif // SINGLEAPPLICATION_H
#include "SingleApplication.h"
#include <QWidget>
#include <QtNetwork/QLocalSocket>
#include <QtNetwork/QLocalServer>
#include <QFileInfo>
#include <QLibrary>
SingleApplication::SingleApplication(int &argc, char **argv)
    : QApplication(argc, argv)
    , bRunning(false)
    , localServer(NULL)
    , mainWindow(NULL)
{
    // 取應(yīng)用程序名作為L(zhǎng)ocalServer的名字
    serverName = QFileInfo(QCoreApplication::applicationFilePath()).fileName();
    //qDebug()<<serverName;
    initLocalConnection();
}
// 說(shuō)明:
// 檢查是否已經(jīng)有一個(gè)實(shí)例在運(yùn)行, true - 有實(shí)例運(yùn)行, false - 沒(méi)有實(shí)例運(yùn)行
bool SingleApplication::isRunning()
{
    return bRunning;
}
// 說(shuō)明:
// 通過(guò)socket通訊實(shí)現(xiàn)程序單實(shí)例運(yùn)行,監(jiān)聽(tīng)到新的連接時(shí)觸發(fā)該函數(shù)
void SingleApplication::newLocalConnection()
{
    QLocalSocket *socket = localServer->nextPendingConnection();
    if (!socket)
        return;
    socket->waitForReadyRead(1000);
    QTextStream stream(socket);
    //其他處理
    delete socket;
    if (mainWindow != NULL)
    {
        //激活窗口
        mainWindow->raise();
        mainWindow->activateWindow();
        mainWindow->setWindowState((mainWindow->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
        mainWindow->show();
    }
}
// 說(shuō)明:
// 通過(guò)socket通訊實(shí)現(xiàn)程序單實(shí)例運(yùn)行,
// 初始化本地連接,如果連接不上server,則創(chuàng)建,否則退出
void SingleApplication::initLocalConnection()
{
    bRunning = false;
    QLocalSocket socket;
    socket.connectToServer(serverName);
    if(socket.waitForConnected(500))
    {
        bRunning = true;
        // 其他處理,如:將啟動(dòng)參數(shù)發(fā)送到服務(wù)端
        QTextStream stream(&socket);
        QStringList args = QCoreApplication::arguments();
        if (args.count() > 1)
            stream << args.last();
        else
            stream << QString();
        stream.flush();
        socket.waitForBytesWritten();
        return;
    }
    //連接不上服務(wù)器,就創(chuàng)建一個(gè)
    newLocalServer();
}
// 說(shuō)明:
// 創(chuàng)建LocalServer
void SingleApplication::newLocalServer()
{
    localServer = new QLocalServer(this);
    connect(localServer, SIGNAL(newConnection()), this, SLOT(newLocalConnection()));
    if(!localServer->listen(serverName))
    {
        // 此時(shí)監(jiān)聽(tīng)失敗,可能是程序崩潰時(shí),殘留進(jìn)程服務(wù)導(dǎo)致的,移除之
        if(localServer->serverError() == QAbstractSocket::AddressInUseError)
        {
            QLocalServer::removeServer(serverName); // <-- 重點(diǎn)
            localServer->listen(serverName); // 再次監(jiān)聽(tīng)
        }
    }
}
#include "mainwindow.h"
#include "SingleApplication.h"
int main(int argc, char *argv[])
{
    //單實(shí)例進(jìn)程,或者說(shuō)防止程序多開(kāi)
    SingleApplication a(argc, argv);
    if (!a.isRunning())
    {        
        MainWindow w;
        //傳入一個(gè)要激活程序的窗口,當(dāng)多開(kāi)時(shí)會(huì)激活已有進(jìn)程的窗口,且多開(kāi)失敗
        a.mainWindow = &w;
        w.show();
        return a.exec();
    }
    return 0;
}

3、使用互斥量和文件鎖

Q_OS_WIN32宏用來(lái)表示編譯運(yùn)行的目標(biāo)平臺(tái)是windows,Q_OS_LINUX則標(biāo)示目標(biāo)為linux

#if defined Q_OS_WIN32   //for win  
#include <windows.h>  
bool checkOnly()  
{  
    //  創(chuàng)建互斥量  
    HANDLE m_hMutex  =  CreateMutex(NULL, FALSE,  L"fortest_abc123" );  
    //  檢查錯(cuò)誤代碼  
    if  (GetLastError()  ==  ERROR_ALREADY_EXISTS)  {  
      //  如果已有互斥量存在則釋放句柄并復(fù)位互斥量  
     CloseHandle(m_hMutex);  
     m_hMutex  =  NULL;  
      //  程序退出  
      return  false;  
    }  
    else  
        return true;  
}  
#endif  
#if defined  Q_OS_LINUX   //for linux  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
#include <unistd.h>  
bool checkOnly()  
{  
    const char filename[]  = "/tmp/lockfile";  
    int fd = open (filename, O_WRONLY | O_CREAT , 0644);  
    int flock = lockf(fd, F_TLOCK, 0 );  
    if (fd == -1) {  
            perror("open lockfile/n");  
            return false;  
    }  
    //給文件加鎖  
    if (flock == -1) {  
            perror("lock file error/n");  
            return false;  
    }  
    //程序退出后,文件自動(dòng)解鎖  
    return true;  
}  
#endif  
int main(int argc, char *argv[])  
{  
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB18030"));  
    QTextCodec::setCodecForTr(QTextCodec::codecForName("GB18030"));  
    Q_INIT_RESOURCE(wisdpsclient);  
    QApplication app(argc, argv);  
    //檢查程序是否 已經(jīng)啟動(dòng)過(guò)  
    if(checkOnly()==false)  
        return 0;  
    Test dialog;  
    dialog.show();  
    return app.exec();  
} 

到此這篇關(guān)于Qt禁止程序多開(kāi)的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Qt 禁止程序多開(kāi)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解C++中typedef 和 #define 的區(qū)別

    詳解C++中typedef 和 #define 的區(qū)別

    這篇文章主要介紹了C++中typedef 與 #define 的區(qū)別,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Cocos2d-x UI開(kāi)發(fā)之CCControlSlider控件類使用實(shí)例

    Cocos2d-x UI開(kāi)發(fā)之CCControlSlider控件類使用實(shí)例

    這篇文章主要介紹了Cocos2d-x UI開(kāi)發(fā)之CCControlSlider控件類使用實(shí)例,本文代碼中包含大量注釋講解了CCControlSlider控件類的使用,需要的朋友可以參考下
    2014-09-09
  • C語(yǔ)言實(shí)現(xiàn)隨機(jī)生成6位數(shù)密碼

    C語(yǔ)言實(shí)現(xiàn)隨機(jī)生成6位數(shù)密碼

    這篇文章主要為大家詳細(xì)介紹了如何使用C語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單而實(shí)用的隨機(jī)密碼生成器,該生成器將生成包含字母、數(shù)字和特殊字符的隨機(jī)密碼,有需要的小伙伴可以參考下
    2023-11-11
  • C語(yǔ)言中魔性的float浮點(diǎn)數(shù)精度問(wèn)題

    C語(yǔ)言中魔性的float浮點(diǎn)數(shù)精度問(wèn)題

    這篇文章主要介紹了魔性的float浮點(diǎn)數(shù)精度問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • C++ 哈夫曼樹(shù)對(duì)文件壓縮、加密實(shí)現(xiàn)代碼

    C++ 哈夫曼樹(shù)對(duì)文件壓縮、加密實(shí)現(xiàn)代碼

    這篇文章主要介紹了C++ 哈夫曼樹(shù)對(duì)文件壓縮、加密實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • C/C++使用C語(yǔ)言實(shí)現(xiàn)多態(tài)

    C/C++使用C語(yǔ)言實(shí)現(xiàn)多態(tài)

    這篇文章主要介紹了C/C++多態(tài)的實(shí)現(xiàn)機(jī)制理解的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下,希望能給你帶來(lái)幫助
    2021-08-08
  • 詳解C語(yǔ)言之實(shí)現(xiàn)通訊錄

    詳解C語(yǔ)言之實(shí)現(xiàn)通訊錄

    這篇文章主要為大家詳細(xì)介紹了用C語(yǔ)言實(shí)現(xiàn)通訊錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C語(yǔ)言實(shí)現(xiàn)求定積分的方法

    C語(yǔ)言實(shí)現(xiàn)求定積分的方法

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)求定積分的方法,涉及C語(yǔ)言操作相關(guān)數(shù)學(xué)函數(shù)的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • C++實(shí)現(xiàn)LeetCode(75.顏色排序)

    C++實(shí)現(xiàn)LeetCode(75.顏色排序)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(75.顏色排序),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++實(shí)現(xiàn)LeetCode(190.顛倒二進(jìn)制位)

    C++實(shí)現(xiàn)LeetCode(190.顛倒二進(jìn)制位)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(190.顛倒二進(jìn)制位),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08

最新評(píng)論

贵德县| 博白县| 名山县| 高尔夫| 九龙城区| 广灵县| 邵武市| 南汇区| 临沭县| 余姚市| 中宁县| 新兴县| 静安区| 邻水| 康平县| 开江县| 城步| 乐至县| 承德县| 大冶市| 枣强县| 台州市| 得荣县| 广河县| 常山县| 于都县| 日喀则市| 乐平市| 江北区| 七台河市| 罗田县| 蒲城县| 西乌珠穆沁旗| 井陉县| 铜鼓县| 海口市| 海丰县| 临洮县| 米林县| 琼结县| 贵州省|