QT实现避免软件重复打开功能

 因为做项目的需要,因此在这里记录一哈。因为我们开发出来的QT软件,在实际的工程运用里面会遇到很多问题。首先是重复点击软件,可能会导致开出多个软件页面,这对于一些硬件设备不太行的场合,会加剧软件运行的不流畅度,因此要考虑如何避免这种情况的发生!!!

在这里附上自己实现的代码(直接写在main.cpp文件里面):

首先需要添加的头文件,有以下内容:其中的QMessagebox是实现,当重复软件打开时候,给出软件提示。


#include <QSystemSemaphore>
#include <QSharedMemory>
#include <QMessageBox>

具体实现代码如下:

//避免软件重复打开
    QSystemSemaphore sema("a",1,QSystemSemaphore::Open);
    sema.acquire();// 在临界区操作共享内存   SharedMemory
    QSharedMemory mem("b");// 全局对象名
    if (!mem.create(1))// 如果全局对象以存在则退出
    {
        QMessageBox::information(0, QObject::tr("提示"),QObject::tr(u8"程序运行中,如有需要请先退出"));
        sema.release();
        return 0;
    }
    sema.release();//释放访问的内存

**************************************************************************************************************

更多方式,可以了解一哈QT的单例化;

单例化是一种设计模式,它保证一个类只有一个实例,并提供一个全局访问点。在QT中,实现单例化有以下几种方法:

  • 使用互斥锁(mutex)保证线程安全,即在获取实例的方法中加锁,避免多个线程同时创建实例。
  • 使用静态局部变量的特性,即在获取实例的方法中定义一个静态局部变量,它会在第一次调用时初始化,并且在C++11标准中是线程安全的。
  • 使用静态内部类的特性,即在类中定义一个静态内部类,它会在第一次使用时加载,并且只有一个实例。
  • 使用枚举类的特性,即使用一个枚举类型来表示单例对象,它可以避免线程同步问题,也可以防止反序列化重新创建新的对象。
  • 使用C++11的std::call_once函数来实现单例模式,它可以保证一个函数只被调用一次,并且是线程安全的。

比如:Q本身自带了一个宏QGLOBALSTATIC,也有类似单例模式的效果。

这里有一个单例化的代码示意,参考如下:

// 定义一个单例类
class Singleton {
public:
  // 获取单例对象的方法
  static Singleton* getInstance() {
    // 定义一个静态局部变量,它会在第一次调用时初始化,并且是线程安全的
    static Singleton instance;
    // 返回该变量的地址,即单例对象的指针
    return &instance;
  }
  // 定义其他的成员函数和变量
  // ...
private:
  // 将构造函数、拷贝构造函数、赋值运算符和析构函数设为私有,防止外部创建或销毁对象
  Singleton() {
    // ... // 初始化代码
  }
  ~Singleton() {
    // ... // 清理代码
  }
  Singleton(const Singleton&) = delete;
  Singleton& operator=(const Singleton&) = delete;
};

上述这段代码的主要逻辑和功能,可以参考以下的内容来学习和理解:

  • 这段代码的目的是定义一个单例类,即一个只能有一个实例的类,并提供一个全局访问点。
  • 首先,定义了一个类名为Singleton,表示这是一个单例类。
  • 然后,在类中定义了一个静态成员函数getInstance,用于获取单例对象的指针。这个函数是类的唯一公有接口,外部只能通过它来访问单例对象。
  • 在getInstance函数中,定义了一个静态局部变量instance,它是Singleton类的一个对象。这个变量会在第一次调用getInstance函数时初始化,并且在C++11标准中是线程安全的,即不会有多个线程同时初始化它。这样就保证了只有一个Singleton对象被创建。
  • 然后,返回instance变量的地址,即单例对象的指针。这样就提供了一个全局访问点,外部可以通过Singleton::getInstance()来获取单例对象。
  • 接下来,在类中定义了其他的成员函数和变量,用于实现类的具体功能。这些成员函数和变量都是私有的,外部无法直接访问它们。
  • 最后,在类中将构造函数、拷贝构造函数、赋值运算符和析构函数都设为私有,并且使用delete关键字禁止拷贝和赋值。这样就防止了外部创建或销毁单例对象,保证了单例模式的正确性。

另一个例子:

要将 Qt 编写的软件缩小到任务栏,可以通过以下步骤实现:
在代码中创建一个 QSystemTray 对象,用于创建系统托盘图标。设置 QSystemTray 对象的图标、标题和菜单等属性。将 QSystemTray 对象添加到 Qt 应用程序的窗口系统中。在代码中实现将应用程序窗口最小化到系统托盘的功能,可以通过调用 QWindow 类的 setWindowState() 函数来实现。
下面是一个简单的示例代码,演示了如何将 Qt 应用程序窗口缩小到任务栏:

#include <QApplication>  
#include <QWidget>  
#include <QSystemTray>  
#include <QMenu>  
#include <QAction>
int main(int argc, char *argv[])  
{
   QApplication app(argc, argv);
   QWidget window;  
   QSystemTray tray;
   // 设置系统托盘图标  
   QIcon icon(":/icons/tray_icon.png");  
   tray.setIcon(icon);
   // 设置系统托盘标题  
   tray.setTitle("My Application");
   // 设置系统托盘菜单  
   QMenu *menu = new QMenu("&File", &tray);  
   QAction *openAction = new QAction("&Open", &tray);  
   QAction *closeAction = new QAction("&Close", &tray);  
   connect(openAction, &QAction::triggered, [=]() {  
       window.show();  
   });  
   connect(closeAction, &QAction::triggered, [=]() {  
       window.close();  
   });  
   menu->addAction(openAction);  
   menu->addAction(closeAction);  
   tray.setMenu(menu);
   // 将系统托盘添加到窗口系统中  
   window.installSystemTray(&tray);
   // 实现将应用程序窗口最小化到系统托盘的功能  
   connect(&tray, &QSystemTray::activated, [=]() {  
       if (tray.isVisible()) {  
           window.setWindowState(QWindow::WindowMinimized);  
       } else {  
           window.setWindowState(QWindow::WindowActive);  
       }  
   });
   window.show();  
   return app.exec();  
}

在上面的示例代码中,我们首先创建了一个 QWidget 对象,用于显示应用程序的主窗口。然后,我们创建了一个 QSystemTray 对象,并设置了它的图标、标题和菜单等属性。接着,我们将 QSystemTray 对象添加到 Qt 应用程序的窗口系统中。最后,我们实现了将应用程序窗口最小化到系统托盘的功能,通过调用 QWindow 类的 setWindowState() 函数来实现。
当用户点击系统托盘图标时,会触发 QSystemTray 对象的 activated 信号,从而实现将应用程序窗口最小化到系统托盘的功能。当应用程序窗口最小化到系统托盘后,用户可以通过右键单击系统托盘图标,然后选择“显示窗口”选项,来恢复应用程序窗口。

除了使用 QSystemTray 实现将应用程序窗口最小化到任务栏外,还可以使用第三方库如 QStyleHint 实现类似的功能。
以下是一个使用 QStyleHint 库的示例代码:

#include <QApplication>  
#include <QWidget>  
#include <QStyleHint>  
#include <QMenu>  
#include <QAction>
int main(int argc, char *argv[])  
{
   QApplication app(argc, argv);
   QWidget window;  
   QStyleHint *styleHint = new QStyleHint();
   // 设置窗口最小化到任务栏的提示信息    
   styleHint->setHint(QStyleHint::TaskBarWindowMinimizeHint, true);
   // 设置系统托盘图标    
   QIcon icon(":/icons/tray_icon.png");  
   styleHint->setHint(QStyleHint::IconSize, QSize(icon.size().width(), icon.size().height()));  
   styleHint->setHint(QStyleHint::IconSpacing, 4);
   // 设置系统托盘标题    
   styleHint->setHint(QStyleHint::TaskBarTitle, "My Application");
   // 设置系统托盘菜单    
   QMenu *menu = new QMenu("&File", window);  
   QAction *openAction = new QAction("&Open", window);  
   QAction *closeAction = new QAction("&Close", window);  
   connect(openAction, &QAction::triggered, [=]() {  
       window.show();  
   });  
   connect(closeAction, &QAction::triggered, [=]() {  
       window.close();  
   });  
   menu->addAction(openAction);  
   menu->addAction(closeAction);
   // 将窗口添加到任务栏    
   window.setWindowState(QWindow::WindowActive);  
   window.installStyleHint(styleHint);
   window.show();  
   return app.exec();  
}

在这个示例中,我们首先创建了一个 QWidget 对象,用于显示应用程序的主窗口。然后,我们创建了一个 QStyleHint 对象,设置了窗口最小化到任务栏的提示信息、系统托盘图标、标题和菜单等属性。接着,我们将窗口添加到任务栏,并安装了 QStyleHint。
这样,当用户点击窗口标题栏时,窗口会最小化到任务栏;当用户右键单击系统托盘图标时,也可以选择“显示窗口”选项,恢复应用程序窗口。
注意:在使用 QStyleHint 时,需要调用 QWidget::installStyleHint() 函数将样式提示安装到窗口上。另外,QStyleHint 仅适用于 Qt 5.15 及更高版本。

猜你喜欢

转载自blog.csdn.net/Helloorld_1/article/details/132183077
今日推荐