質問

I am writing a Qt application that does some heavy computations, but on a Mac (potentially also on Windows but I currently have no way of checking this), the execution ceases as soon as the computer goes into sleeping mode.

I would like a way to continue the execution even when the screen goes to screensaver or on blank. Obviously you can ask the user to change his/her energy settings, but that's far from an ideal solution. Is there a proper way of doing this?

役に立ちましたか?

解決

After a thorough search through the Qt 5.2 API, it seems that Qt doesn't offer any functionality to change the energy settings (so neither for Mac, nor any other operating system). I haven't found any indication that it's on their road map either.

A possible solution for Mac OSX using Apple's Objective-C API can be found here (thanks, @Kuba).

On Windows, power settings can be dealt with using the SetThreadExecutionState function (see this question, C#).

他のヒント

There are two aspects of this:

  1. Forced Sleep If the user intends the system to sleep, and you prevent it, your users may well curse you. Forced sleep is also part of energy and thermal management, and is vital to prevent data loss and avoid destruction of hardware and mitigate possible fire risk.

    When I close the lid of my laptop, it better go to sleep and if I find an app that tries to circumvent it, it better be free or else I'm calling my credit card company for a chargeback. It's that simple, and I hope it's easy to understand why it would be so.

  2. Idle Sleep What you want to do is not to prevent the system from going to sleep at all, but to only disable the idle sleep.

Disabling of idle sleep is covered in this answer.

If you want to avoid the Objective-C API, there's a C-based API underlying it. You can call IOPMAssertionCreateWithDescription() with an assertion type of kIOPMAssertionTypePreventUserIdleSystemSleep. That gives you an assertion ID reference. You cancel the assertion using IOPMAssertionRelease() to match the create call and any IOPMAssertionRetain() calls you may have made.

CFURLRef bundleURL = CFBundleCopyBundleURL(CFBundleGetMainBundle());
CFStringRef bundlePath = CFURLCopyFileSystemPath(bundleURL, kCFURLPOSIXPathStyle);
CFRelease(bundleURL);

IOPMAssertionID assertion;
IOReturn result = IOPMAssertionCreateWithDescription(kIOPMAssertionTypePreventUserIdleSystemSleep,
    CFSTR("A name which makes sense for your app"),
    CFSTR("Some details"), CFSTR("A human-readable reason"),
    bundlePath, 0, NULL, &assertion);
CFRelease(bundlePath);
if (result != kIOReturnSuccess)
    /* handle error */;

// ... do computation ...

IOPMAssertionRelease(assertion);

There seems to be a command line utility "caffeinate" that prevents system from going to sleep. Here is an example of using this utility within QT framework:

https://github.com/githublucas420/KDE/blob/4436536a6a2beb1631f89968dfab566963dae073/plugins/screensaver-inhibit/screensaverinhibitplugin-macos.cpp

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top