QSplashScreen 不使用与 QMainWindow 相同的默认监视器

Posted

技术标签:

【中文标题】QSplashScreen 不使用与 QMainWindow 相同的默认监视器【英文标题】:QSplashScreen Does Not Use Same Default Monitor as QMainWindow 【发布时间】:2016-10-11 00:20:33 【问题描述】:

我有一个在 Windows 上运行的基于 Qt 的应用程序,它在进行一些初始化时显示一个 QSplashScreen,然后我打开一个 QMainWindow。无论 QMainWindow 使用何种监视器,初始屏幕始终显示在监视器 0 上。例如,如果我从监视器 0 上的命令提示符启动应用程序,则启动屏幕和主窗口都会出现在监视器 0 上。如果我从监视器 1 上的命令提示符启动应用程序,启动屏幕会出现在监视器 0 上,并且监视器 1 上的主窗口。

非常清楚:我并不是要控制主窗口使用哪个监视器;我唯一的愿望是检测它将使用哪一个,然后让启动画面出现在同一台显示器上。我知道关于如何控制窗口使用哪个监视器还有其他问题,这不是我想要理解的。从我下面的调试代码中可以很明显地看出,Windows 正在以某种方式决定使用哪个监视器,而我正试图弄清楚如何在不显示任何内容的情况下知道这一点。这也很明显不是关于主显示器的。否则,我的主窗口将始终出现在主监视器上,但它不会。此外,我没有任何代码可以保存/恢复窗口位置。 Windows 和/或 Qt 正在使用它们的默认值定位主窗口和启动屏幕。

我输入了一些调试代码如下:

QSplashScreen splash (QPixmap (":/splash.png"));
splash.show ();
qDebug () << __LINE__ << "Splash screen monitor: " << app->desktop ()->screenNumber (&splash);  // Line 114 in output
app->processEvents ();

// Do a bunch of behind-the-scenes visualization.

aBunchOfStuff ();

// Create and activate main window.

QMainWindow *main_wnd = new QMainWindow ();
qDebug () << __LINE__ << "Main window monitor (created): " << app->desktop ()->screenNumber (main_wnd); // Line 139 in output
main_wnd->show ();
qDebug () << __LINE__ << "Main window monitor (shown):   " << app->desktop ()->screenNumber (main_wnd); // Line 141 in output

命令提示符在监视器 0 上时的输出:

10/10/16 16:06:53: Debug: 114 Splash screen monitor: 0
10/10/16 16:06:54: Debug: 139 Main window monitor (created): 0
10/10/16 16:06:54: Debug: 141 Main window monitor (shown):   0

命令提示符在监视器 1 上时的输出:

10/10/16 16:07:01: Debug: 114 Splash screen monitor: 0
10/10/16 16:07:03: Debug: 139 Main window monitor (created): 0
10/10/16 16:07:03: Debug: 141 Main window monitor (shown):   1 

如您所见,在创建和显示之间,当命令提示符位于监视器 1 上时,主窗口的监视器编号从 0 变为 1。

使用我所知道的使用 QDesktopWidget 的任何技术,在我实际显示之前,我似乎无法知道主窗口将出现在哪个监视器上。我考虑在显示启动屏幕之前创建一个虚拟窗口,但我不希望屏幕上出现任何闪烁,并且第 139 行和第 141 行之间的输出显示该小部件在使其可见之前不知道它是监视器。

是否有某种方法(无论是使用 Qt 代码还是 Windows API)来了解 Windows 已分配给我的应用程序的默认监视器?

【问题讨论】:

可能是闪屏小部件可以追溯到以前闻所未闻的多显示器... 我不知道,而且这种行为似乎是 QSplashScreen 中的一个错误,因为它不遵守相同的规则。但是,我的问题是如何找出哪个监视器 Windows 将我的应用程序的主窗口放在上面?如果我有,我假设/希望我可以将启动画面设置在同一个窗口上。 【参考方案1】:

由于窗口会在屏幕上显示您的应用程序,其中包含您的光标,因此您可以使用以下命令获取当前屏幕编号

QApplication::desktop()->screenNumber(QCursor::pos())

要将初始屏幕移动到此屏幕,请使用:

QSplashScreen* splash = new QSplashScreen;

QDesktopWidget* desktop = QApplication::desktop();
const int scrn = desktop->screenNumber(QCursor::pos());
const QPoint currentDesktopsCenter = desktop->availableGeometry(scrn).center();
splash->move(currentDesktopsCenter - splash->rect().center());
splash->show();

【讨论】:

以上是关于QSplashScreen 不使用与 QMainWindow 相同的默认监视器的主要内容,如果未能解决你的问题,请参考以下文章

Qt C++ - 在 QSplashScreen 内对齐 QProgressBar

QSplashScreen 消失得太快

qt qsplashscreen 怎么声明

QSplashScreen无法背景透明的解决办法(强制StyleSheet生效)

qt 如何显示动态开机画面

将 QMainWindow 与 Qdialog 小部件连接起来