在Qt 5,什么是正确的方法来显示多显示器全屏QWidget窗口? [英] In Qt 5, what's the right way to show multi-monitor full screen QWidget windows?

查看:3633
本文介绍了在Qt 5,什么是正确的方法来显示多显示器全屏QWidget窗口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Windows& Mac程序,在多个显示器上切换到全屏模式。在Qt 4,似乎(我找不到明确的文档,如何做到这一点)像'正确'的方式去做这是通过创建N QMainWindow '对于机器上的N个监视器,调用 QWidget :: move()到N监视器的左上角的x,y坐标,然后调用 QWidget :: setWindowState(Qt :: WindowFullScreen)。我不知道这是否是正确的事情 - 再次,我找不到任何文档或示例在Qt这样做。

I have a Windows & Mac program that switches into full-screen mode on multiple monitors. In Qt 4, it seems (I can't find explicit documentation on how to do this) like the 'correct' way to go about this is by creating N QMainWindow's for the N monitors on the machine, calling QWidget::move() to the N monitor's top-left x,y coordinates, and then calling QWidget::setWindowState(Qt::WindowFullScreen). I don't know whether this is The Right Thing To Do - again, I can't find any documentation or examples anywhere that do this in Qt.

这在Qt 5.4.1,尤其是在Windows 7上,似乎是破碎(如果它是第一次做正确的事情) m仍然试图隔离问题,但似乎 QMainWindow 正在退出全屏模式。

This seems to be 'broken' (if it was ever the Right Thing To Do in the first place) in Qt 5.4.1, especially on Windows 7. I'm still trying to isolate the problem, but it seems like the QMainWindows are dropping out of full-screen mode.

所以我很清楚,这是什么正确的方法?我找到了论坛帖子这似乎暗示我应该设置 QWindow 对象的 QScreen c $ c> QMainWindow s,但是这在我的测试中似乎不工作。以下是我写的示例程序:

Just so I'm clear about this, what is the right way to do this? I found this forum post which seems to suggest that I should be setting the QScreen on the underlying QWindow objects that are held by the QMainWindows, but this doesn't seem to work in my tests. Here's an example program that I wrote:

app.h:

#include <vector>
#include <QObject>

class QMainWindow;

class app : public QObject
{
    Q_OBJECT
public:
    int run(int argc, char** argv);

public slots:
    void add_window();
    void remove_window();
    void windows_go_to_screens();
    void windows_go_to_screens_old();
    void windows_go_to_primary_screen();
    void windows_fullscreen();
    void windows_nonfullscreen();

private:
    QMainWindow * create_window(const char * id);
    void init_menus( QMainWindow * w );

    std::vector<QMainWindow *> m_windows;
};

app.cpp:

#include <assert.h>
#include <algorithm>
#include <iostream>
#include <vector>
#include <QObject>
#include <QMainWindow>
#include <QApplication>
#include <QMenubar>
#include <QAction>
#include <QScreen>
#include <QWindow>
#include <QLayout>
#include <QLabel>
#include <QStyle>

#include "app.h"

using namespace std;

int app::run(int argc, char** argv)
{
    QApplication a(argc, argv);
    QMainWindow * w = create_window("0");
    m_windows.push_back(w);
    w->show();
    return a.exec();
}

void app::add_window()
{
    static const char * nums[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
    m_windows.push_back(create_window(nums[m_windows.size()]));
    m_windows.back()->show();
}

void app::remove_window()
{
    if (m_windows.size() > 1)
    {
        QMainWindow * w = m_windows.back();
        m_windows.pop_back();
        w->close();
        w->deleteLater();
    }
}

void app::windows_go_to_screens()
{
    QList<QScreen*> screens = qApp->screens();

    for (unsigned i = 0; i < std::min((unsigned)m_windows.size(), (unsigned)screens.size()); ++i)
    {
        QMainWindow * mw = m_windows[i];
        QScreen * screen = screens[i];
        QWindow * wh = mw->windowHandle();
        wh->setScreen(screen);
    }
}

void app::windows_go_to_screens_old()
{
    QList<QScreen*> screens = qApp->screens();

    for (unsigned i = 0; i < std::min((unsigned)m_windows.size(), (unsigned)screens.size()); ++i)
    {
        QMainWindow * mw = m_windows[i];
        QScreen * screen = screens[i];
        mw->move(screen->geometry().left(), screen->geometry().top());
    }
}

void app::windows_go_to_primary_screen()
{
    QList<QScreen*> screens = qApp->screens();

    for (unsigned i = 0; i < std::min((unsigned)m_windows.size(), (unsigned)screens.size()); ++i)
    {
        QMainWindow * mw = m_windows[i];
        QScreen * screen = screens[0];
        QWindow * wh = mw->windowHandle();
        wh->setScreen(screen);
    }
}

void app::windows_fullscreen()
{
    for (unsigned i = 0; i < m_windows.size(); ++i)
    {
        QMainWindow * mw = m_windows[i];
        mw->showFullScreen();
    }
}

void app::windows_nonfullscreen()
{
    for (unsigned i = 0; i < m_windows.size(); ++i)
    {
        QMainWindow * mw = m_windows[i];
        mw->showNormal();
    }
}



QMainWindow * app::create_window(const char * id)
{
    QMainWindow * w = new QMainWindow(NULL);
    init_menus(w);
    QWidget * cw = new QWidget(w);
    w->setCentralWidget(cw);
    QHBoxLayout * l = new QHBoxLayout(cw);
    cw->setLayout(l);
    QLabel * lab = new QLabel(id, cw);
    QPalette pal(lab->palette());
    pal.setColor(QPalette::Background, Qt::red);
    lab->setAutoFillBackground(true);
    lab->setPalette(pal);
    lab->setScaledContents(true);
    lab->setAlignment(Qt::AlignCenter);
    l->addWidget( lab );
    return w;
}

void app::init_menus( QMainWindow * w )
{
    QMenuBar * menubar = w->menuBar();
    QMenu * view_menu = new QMenu(tr("View"), w);
    view_menu->addAction("Add Window", this, SLOT(add_window()));
    view_menu->addAction("Remove Window", this, SLOT(remove_window()));
    view_menu->addAction("Windows Go To Screens", this, SLOT(windows_go_to_screens()));
    view_menu->addAction("Windows Go To Screens (old method)", this, SLOT(windows_go_to_screens_old()));
    view_menu->addAction("Windows Go To Primary Screen", this, SLOT(windows_go_to_primary_screen()));
    view_menu->addAction("Windows Fullscreen", this, SLOT(windows_fullscreen()));
    view_menu->addAction("Windows Non-Fullscreen", this, SLOT(windows_nonfullscreen()));
    menubar->addMenu(view_menu);
}

main.cpp:

#include "app.h"

int main(int argc, char** argv)
{
    app a;
    return a.run(argc, argv);
}



当我在OS X上运行此程序时,Windows Go To Screens函数什么也不做 - 没有窗口移动。 Windows转到主屏幕(命名不正确 - 应该是0屏幕吗?)。在N窗口上创建多于N个窗口Mac很有趣 - 在这种情况下,多次调用Windows全屏实际上会将QMainWindows一次切换到全屏模式?

When I run this program on OS X, the "Windows Go To Screens" function does nothing - none of the windows move. Neither does the "Windows Go To Primary Screen" (poorly named - should be 0 screen?). Creating more than N windows on an N window Mac is interesting - in that case calling "Windows Fullscreen" several times will actually switch the QMainWindows into fullscreen mode one at a time?!

更有趣的是在多显示器OS X机器上执行以下操作时会发生什么:添加窗口,直到您拥有与显示器一样多的窗口。 Windows转到屏幕(旧方法)将每个窗口发送到每个显示器的左上角。 Windows全屏将使所有窗口在所有显示器上全屏。 删除窗口,直到您只剩下1个窗口。然后Windows非全屏,你会得到一个有趣的惊喜。进入任务控制,看看发生了什么。

Even more interesting is what happens on a multi-monitor OS X machine when you do this: "Add Window" until you have as many windows as displays. "Windows Go To Screens (old method)" will send each window to the top-left of each monitor. "Windows Fullscreen" will make all windows go full-screen on all monitors. "Remove Window" until you have only 1 window left. Then "Windows Non-FullScreen", and you'll get an interesting surprise. Go into Mission Control to see what's going on.

任何人都可以告诉我 RIGHT 的方法是什么?我看过Qt5示例 - 有播放器应用程序,似乎彻底打破了(它可以播放视频全屏模式一次,然后后续播放在一个单独的桌面窗口),子游戏只最大化到单个显示器,没有其他示例似乎使用全屏模式,当然不在多个显示器上。

Can anyone tell me what the RIGHT way of doing this is? I've looked through the Qt5 examples - there's the player application that seems to be thoroughly broken (it can play a video in full-screen mode once, and then subsequent plays are in a separate desktop window), the sub game only maximizes to a single display, and none of the other examples seem to utilize full-screen mode, and certainly not on multiple monitors.

推荐答案

在Qt5中执行此操作的一种方法是使用 QWindow :: setScreen 设置应显示窗口的屏幕。 QWidget 有一个 windowHandle(),返回 QWindow

One way of doing it in Qt5 is to use QWindow::setScreen to set the screen on which the window should be shown. QWidget has a windowHandle() that returns the pointer to the QWindow. So you can get that pointer for each window and set a different screen.

这是如何在全屏模式下在最后一个屏幕上显示你的小部件:

Here is how to show your widget in the last screen in full-screen mode :

QWidget * widget = new QWidget();
widget->show();
widget->windowHandle()->setScreen(qApp->screens().last());
widget->showFullScreen();

或在第二个屏幕中:

QWidget * widget = new QWidget();
widget->show();
widget->windowHandle()->setScreen(qApp->screens()[1]);
widget->showFullScreen();

这篇关于在Qt 5,什么是正确的方法来显示多显示器全屏QWidget窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆