限制qt开发的程序只能打开一个(使用QLocalServer和QLocalSocket)

背景

某些情况下,在Windows环境,用qt开发的程序想限制用户只能同时打开一个。

用 QLocalSocket 和 QLocalServer实现

思路:程序运行时,先创建一个socket,去连接指定名字的本地服务器。
1)如果连接上了,则说明已经存在一个app被启动了,则关闭此套接字。退出程序启动。
2)如果没连上,则创建一个指定名称的服务器。

代码:
SingleApplication.cpp

#include "SingleApplication.h"
#include <QFileInfo>
#include <QtNetwork/QLocalSocket>
/*
 * QLocalSocket 和 QLocalServer 是在和本机通信时使用,无法跨主机。(本地进程间套接字通信)
 */
#define TIME_OUT 500  //500ms
SingleApplication::SingleApplication(int &argc, char **argv)
    :QApplication(argc, argv)
{
    m_server_name = QFileInfo(QCoreApplication::applicationFilePath()).fileName();
    InitConnect();
}

bool SingleApplication::IsRunning()
{
    return m_is_running;
}

void SingleApplication::InitConnect()
{
    m_is_running = false;
    QLocalSocket socket;
    socket.connectToServer(m_server_name);
    bool ret = socket.waitForConnected(TIME_OUT);
    if (ret) {
        fprintf(stderr, "%s already running.\n",
                m_server_name.toLocal8Bit().constData());
        m_is_running = true;
        /**其他处理,如 将启动参数发送到服务端**/

        //!!!注释中带中文且用想/**/注释时,如果是只有一行,最好用/**xxx**/形式,因为由于编码问题,
        //末尾的*/会被转码,导致程序运行不报错,但是实际上运行跟理想的顺序不一致
        return;
    }

    //连接不上服务器,就创建一个
    NewLocalServer();
}

void SingleApplication::NewLocalServer()
{
    m_server = new QLocalServer(this);
    connect(m_server, &QLocalServer::newConnection, this, &SingleApplication::NewLocalConnect);
    if (!m_server->listen(m_server_name)) {
        if (m_server->serverError() == QAbstractSocket::AddressInUseError) {
            QLocalServer::removeServer(m_server_name);
            m_server->listen(m_server_name);
        }
    }
}

void SingleApplication::NewLocalConnect()
{
    QLocalSocket* socket = m_server->nextPendingConnection();
    if (socket)
    {
        socket->waitForReadyRead(2 * TIME_OUT);
        delete socket;

        /*其他处理,如读取启动参数*/
        ActiveMainWindows();
    }
}

void SingleApplication::ActiveMainWindows()
{
    if (m_widget)
    {
        m_widget->show();
        m_widget->raise();
        m_widget->activateWindow();// 激活窗口
    }
}

SingleApplication .h

#pragma once
#include <QObject>
#include <QWidget>
#include <QApplication>
#include <QtNetwork/QLocalServer>

class SingleApplication : public QApplication
{
    Q_OBJECT
public:
    SingleApplication(int& argc, char** argv);
    bool IsRunning();//是否已有运行的程序
private:
    void InitConnect();
    void NewLocalServer();
    /**
     * @brief NewLocalConnect  通过socket通讯实现程序单实例运行,监听到新的连接时触发该函数
     */
    void NewLocalConnect();
    /**
     * @brief ActiveMainWindows 激活主窗口
     */
    void ActiveMainWindows();
public:
    QWidget *m_widget{nullptr};
private:
    bool m_is_running{false};
    QLocalServer *m_server{nullptr};
    QString m_server_name{""};
};


main.cpp

	SingleApplication app(argc, argv);
    if (!app.IsRunning())
    {
        MainWindow w;
        app.m_widget = &w;
        w.show();
        return app.exec();
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在Qt的QLocalServer和QLocalSocket之间相互发送消息,您需要遵循以下步骤: 1. 在QLocalServer中,使用`newConnection()`信号来接受来自客户端的新连接,并在连接成功时创建一个QLocalSocket实例,并保存该实例以便稍后使用。 2. 在QLocalSocket中,使用`connected()`信号来检测与服务器的连接是否成功,并在连接成功时使用`write()`函数向服务器发送消息。 3. 在QLocalServer中,使用`readyRead()`信号来检测来自客户端的消息,并使用`readAll()`函数读取所有可用的字节数据。 4. 在QLocalSocket中,使用`readyRead()`信号来检测来自服务器的消息,并使用`readAll()`函数读取所有可用的字节数据。 下面是一个简单的示例代码,演示如何在QLocalServer和QLocalSocket之间相互发送消息: ```cpp // Server QLocalSocket *clientConnection; QLocalServer *server = new QLocalServer(this); if (!server->listen("myserver")) { qDebug() << "Unable to start the server: " << server->errorString(); return; } // accept new connections connect(server, &QLocalServer::newConnection, [&](){ clientConnection = server->nextPendingConnection(); }); // handle incoming messages from client connect(clientConnection, &QLocalSocket::readyRead, [&](){ QByteArray message = clientConnection->readAll(); qDebug() << "Received message from client: " << message; }); // Client QLocalSocket *socket = new QLocalSocket(this); // connect to the server socket->connectToServer("myserver"); // handle connection success connect(socket, &QLocalSocket::connected, [&](){ qDebug() << "Connected to server"; socket->write("Hello from client"); }); // handle incoming messages from server connect(socket, &QLocalSocket::readyRead, [&](){ QByteArray message = socket->readAll(); qDebug() << "Received message from server: " << message; }); ``` 这里我们在QLocalServer中监听名为“myserver”的本地套接字,并在`newConnection()`信号中接受新连接。在客户端连接成功后,我们使用`write()`函数向服务器发送消息。在QLocalServer中,我们使用`readyRead()`信号来检测来自客户端的消息,并使用`readAll()`函数读取所有可用的字节数据。在QLocalSocket中,我们使用`readyRead()`信号来检测来自服务器的消息,并使用`readAll()`函数读取所有可用的字节数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值