Qt for Mac阻止MacOS系统休眠

Qt开发的应用程序如果电脑休眠了会影响软件的使用,因此在软件的使用过程中需要防止电脑休眠,在Win上有专门的API进行处理,在Mac上也必需使用Mac平台自身的API,本篇介绍在Mac平台下使用Qt阻止Mac系统休眠。

要调用Mac系统的API,得需要添加Object- C的语言文件,这里得创建两个文件mactools.h和 mactools.mm的文件

在工程文件中添加Mac的库

cpp 复制代码
mac:{
#    DEFINES += PRODUCT
    LIBS += -framework IOKit
    LIBS += -framework CoreFoundation

    OBJECTIVE_SOURCES += mactools.mm
    OBJECTIVE_HEADERS += mactools.h
    #程序图标
#    ICON = logo.icns
    VERSION = 2.0.1.1
}

休眠功能代码:

//官方例子用的文字说明
CFStringRef reasonForActivity = CFSTR("QtforMac App");
IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, reasonForActivity, &assertionID);

软件退出后,得还电脑原休眠状态

复制代码
IOReturn success = IOPMAssertionRelease(assertionID);

完整的代码如下:

QtPreventSystemSleep.pro

cpp 复制代码
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
#mac环境配置
mac:{
#    DEFINES += PRODUCT
    LIBS += -framework IOKit
    LIBS += -framework CoreFoundation

    OBJECTIVE_SOURCES += mactools.mm
    OBJECTIVE_HEADERS += mactools.h
    #程序图标
#    ICON = logo.icns
    VERSION = 2.0.1.1
}

SOURCES += \
    main.cpp \
    dialog.cpp

HEADERS += \
    dialog.h

FORMS += \
    dialog.ui


# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

mactools.h

cpp 复制代码
#ifndef MACTOOLS_H
#define MACTOOLS_H

/*
 * brief: Mac系统阻止休眠
 * author:chenyijun
 * date:  2024-03-17
 */

class MacTools {
public:
    bool preventSleep();
    bool recoverSleep();

private:
    bool isPrevent{false};
};

#endif // MACTOOLS_H

mactools.cpp文件

cpp 复制代码
#include "mactools.h"
#import <CoreFoundation/CoreFoundation.h>  //mac头文件
#import <IOKit/pwr_mgt/IOPMLib.h>            //mac头文件
#include <QDebug>
#include <QDateTime>

#define PRINTTIME QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz");


IOPMAssertionID assertionID;

bool MacTools::preventSleep()
{
    //限制不重复执行
    if(isPrevent)
        return true;

    //官方例子用的文字说明
    CFStringRef reasonForActivity = CFSTR("AtomStack Studio");
    IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, reasonForActivity, &assertionID);
    isPrevent = (success == kIOReturnSuccess);
    qDebug() << __FUNCTION__ << " isPrevent=============" << isPrevent << assertionID << PRINTTIME;
    return isPrevent;
}

bool MacTools::recoverSleep()
{
    //执行过才支持取消
    if(!isPrevent)
        return true;

    IOReturn success = IOPMAssertionRelease(assertionID);
    qDebug() << __FUNCTION__ << " isPrevent=============" << isPrevent << assertionID << PRINTTIME;
    return success == kIOReturnSuccess;
}

dialog.h

cpp 复制代码
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

class QTimer;

QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = nullptr);
    ~Dialog();
    void initData();

private:
    Ui::Dialog *ui;
    QTimer *m_timer;
};
#endif // DIALOG_H

dialog.cpp

cpp 复制代码
#include "dialog.h"
#include "ui_dialog.h"
#include <QTimer>
#include <QDateTime>
#include <QDebug>

//#define PRINTTIME QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz");

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);
    this->setWindowTitle("Qt for Mac 阻止系统休眠");
    initData();
}

Dialog::~Dialog()
{
    delete ui;
}

void Dialog::initData()
{
    QFont font = qApp->font();
    font.setPixelSize(20);
    ui->label->setFont(font);
    ui->label->setStyleSheet("QLabel{background-color:#0000ff;color:#FF0000;}");
    ui->label->setAlignment(Qt::AlignCenter);

    m_timer = new QTimer();
    QObject::connect(m_timer, &QTimer::timeout, [&]() {
        //QString strTime = QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss");
        QString strTime = QDateTime::currentDateTime().toString("hh:mm:ss");
        ui->label->setText(strTime);
        ui->label->update();
        qDebug() << "strTime==========================" << strTime;
    });
    m_timer->start(1000);
}

main.cpp

阻止系统休眠使用代码

cpp 复制代码
#include "dialog.h"

#include <QApplication>


#ifdef Q_OS_MAC
#include "mactools.h"
#endif

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
#ifdef Q_OS_MAC
    //开启阻止休眠
    MacTools macTools;
    macTools.preventSleep();
#endif

    Dialog w;
    w.show();
    int ret = a.exec();
#ifdef Q_OS_MAC
    //程序退出还原系统休眠状态
    macTools.recoverSleep();
#endif
    return ret;
}

运行:

参考:

Qt Mac阻止和启用休眠_mac休眠api-CSDN博客