因为做项目的需要,因此在这里记录一哈。因为我们开发出来的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 及更高版本。