在Qt 5中,显示多显示器全屏QWidget窗口的正确方法是什么?

时间:2015-05-07 23:25:18

标签: c++ qt qt5 fullscreen

我有一个Windows&在多台显示器上切换到全屏模式的Mac程序。在Qt 4中,似乎(我无法找到关于如何执行此操作的明确文档),例如'正确'解决这个问题的方法是为机器上的N个监视器创建N QMainWindow,将QWidget::move()调用到N监视器的左上角x,y坐标,以及然后打电话给QWidget::setWindowState(Qt::WindowFullScreen)。我不知道这是否是正确的事 - 再次,我无法在Qt中找到任何文档或示例。

这似乎被打破了#39; (在Qt 5.4.1中,如果它一直是正确的事情),特别是在Windows 7上。我仍然试图找出问题,但似乎QMainWindow是退出全屏模式。

就这样,我清楚这一点,做到这一点的正确方法是什么?我发现this论坛帖子似乎暗示我应该在QScreen s所持有的基础QWindow对象上设置QMainWindow,但这并不是&#39} ;似乎在我的测试中工作。这是我写的一个示例程序:

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上运行此程序时,&#34; Windows转到屏幕&#34;函数什么都不做 - 没有窗户移动。 &#34; Windows转到主屏幕&#34; (名字不好 - 应该是0屏?)。在N窗口上创建超过N个窗口Mac很有意思 - 在这种情况下调用&#34; Windows全屏&#34;有几次实际上会将QMainWindows一次切换到全屏模式?!

更有趣的是,当您执行此操作时,多显示器OS X机器上会发生什么:&#34;添加窗口&#34;直到你拥有与显示器一样多的窗口。 &#34; Windows转到屏幕(旧方法)&#34;将每个窗口发送到每个监视器的左上角。 &#34; Windows全屏&#34;将使所有窗口全屏显示在所有显示器上。 &#34;删除窗口&#34;直到你只有一个窗口。然后&#34; Windows Non-FullScreen&#34;,你会得到一个有趣的惊喜。进入Mission Control查看正在进行的操作。

有谁能告诉我 RIGHT 的做法是什么?我已经查看了Qt5的例子 - 那里的播放器应用程序似乎彻底被破坏了(它可以在全屏模式下播放一次视频,然后后续播放在一个单独的桌面窗口中),子游戏只能最大化为单个显示器,其他示例似乎都没有使用全屏模式,当然也不能在多个显示器上使用。

1 个答案:

答案 0 :(得分:9)

在Qt5中执行此操作的一种方法是使用QWindow::setScreen来设置应显示窗口的屏幕。 QWidgetwindowHandle(),返回指向QWindow的指针。因此,您可以为每个窗口获取该指针并设置不同的屏幕。

以下是如何在全屏模式下在最后一个屏幕中显示您的小部件:

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();