Qt 程序单例运行,当已经运行时自动显示置顶已运行的程序(互斥量)

本文介绍了一个使用互斥量实现的单例程序检测方法,并通过信号量机制确保了程序实例的唯一性。此外,还展示了如何利用Qt框架进行界面初始化与字体加载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 单例程序检测:

#include "speechfusion.h"
#include <QtWidgets/QApplication>
#include <QFontDatabase>
#include <QSharedMemory>
#include <QMessageBox>
#include "WaitSignal.h"
#include <qmutex.h>
#include <windows.h>
using namespace std;

bool CheckOnly()
{
	//  创建互斥量  //获取名SpeechFusion的句柄如,果返回的是一个有效句柄,但指定的名字已经存在,GetLastError也会设为ERROR_ALREADY_EXISTS
	HANDLE m_hMutex = CreateMutex(NULL, FALSE, L"SpeechFusion");

	//  检查错误代码  
	if (GetLastError() == ERROR_ALREADY_EXISTS) {
		//  如果已有互斥量存在,获取控制权并等待两秒
		while (true)
		{
			DWORD ret = WaitForSingleObjectEx(m_hMutex, 200, true);
			if (ret == WAIT_OBJECT_0)
			{
				_sleep(500);
				ReleaseMutex(m_hMutex);
				break;
			}
		}

		//释放句柄并复位互斥量  
		CloseHandle(m_hMutex);
		m_hMutex = NULL;

		//  程序退出  
		return  false;
	}
	else
		return true;
}

int main(int argc, char *argv[])
{
	if (CheckOnly())
	{ 
		QApplication a(argc, argv);
		
		int nIndex = QFontDatabase::addApplicationFont(":/SpeechFusion/Resources/SourceHanSansCN-Normal.otf"); //加载字体  
		if (nIndex != -1)
		{
			QStringList strList(QFontDatabase::applicationFontFamilies(nIndex));
			if (strList.count() > 0)
			{
				QFont fontThis(strList.at(0));
				fontThis.setPointSize(14);
				fontThis.setBold(true);
				fontThis.setWeight(QFont::Normal);
				a.setFont(fontThis);
			}
		}
		SpeechFusion::GetInstance()->initView();
		SpeechFusion::GetInstance()->show();//显示界面
		WaitSignal *w = new WaitSignal(NULL);
		return a.exec();
	}
}

等待信号量程序:

#pragma once
#include <QObject>
#include <windows.h>
#include <QTimer>
class WaitSignal :public QObject
{
public:
	WaitSignal(QObject *parent);
	~WaitSignal();
public slots:
	void slot_WaitOtherOpenTimer_timeOut();
private:
	HANDLE m_hMutex;
	QTimer waitOtherOpenTimer;
};

 

#include "WaitSignal.h"
#include "speechfusion.h"
#include <QFontDatabase>

WaitSignal::WaitSignal(QObject *parent)
	: QObject(parent)
{
	m_hMutex = CreateMutex(NULL, FALSE, L"SpeechFusion");

	waitOtherOpenTimer.setInterval(10);
	waitOtherOpenTimer.setSingleShot(false);
	connect(&waitOtherOpenTimer, SIGNAL(timeout()), this, SLOT(slot_WaitOtherOpenTimer_timeOut()));
	waitOtherOpenTimer.start();
}

WaitSignal::~WaitSignal()
{

}

void WaitSignal::slot_WaitOtherOpenTimer_timeOut()
{
	DWORD ret = WaitForSingleObject(m_hMutex, 0);

	//没有拿到句柄,说明程序已经启动
	if (ret == WAIT_TIMEOUT)
	{	
		//1
// 		SpeechFusion::GetInstance()->activateWindow();
// 		SpeechFusion::GetInstance()->show();//显示界面
// 		SpeechFusion::GetInstance()->raise();

		//2
		SpeechFusion::GetInstance()->activateWindow();
		SpeechFusion::GetInstance()->setWindowState((SpeechFusion::GetInstance()->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);

		//3
		//设置窗口置顶
// 		::SetWindowPos(HWND(SpeechFusion::GetInstance()->winId()), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
// 		::SetWindowPos(HWND(SpeechFusion::GetInstance()->winId()), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
// 		SpeechFusion::GetInstance()->show();
// 		SpeechFusion::GetInstance()->activateWindow();
	}
	else if (ret == WAIT_OBJECT_0) {
		ReleaseMutex(m_hMutex);
	}
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值