Dans Qt 5, Quelle est la bonne façon de montrer multi-moniteur plein écran QWidget windows?

J'ai un programme Windows & Mac qui passe en mode plein écran sur plusieurs moniteurs. Dans Qt 4, il semble (Je ne trouve pas de documentation explicite sur la façon de faire cela) que la façon "correcte" de faire ceci est en créant N QMainWindow's pour les n Moniteurs sur la machine, appelant QWidget::move() aux coordonnées x,y, en haut à gauche du n monitor, puis en appelant QWidget::setWindowState(Qt::WindowFullScreen). Je ne sais pas si c'est la bonne chose à faire - encore une fois, Je ne peux trouver aucune documentation ou des exemples n'importe où qui font cela dans Qt.

cela semble être "cassé" (si c'était la bonne chose à faire en premier lieu) dans Qt 5.4.1, en particulier sur Windows 7. J'essaie toujours d'isoler le problème, mais il semble que le QMainWindows abandonnent le mode plein écran.

juste pour être clair, quelle est la bonne façon de faire ça? J'ai trouvé forum post qui semble suggérer que je devrais mettre le QScreen sur le sous-jacent QWindow les objets qui sont détenus par le QMainWindows, mais cela ne semble pas fonctionner dans mes tests. Voici un exemple de programme que j'ai écrit:

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.rpc:

#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.rpc:

#include "app.h"

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

quand J'exécute ce programme sur OS X, la fonction" Windows Go to Screens " ne fait rien - aucune des fenêtres ne bouge. Ni l'un ni l'autre ne "Windows Go To Primary Screen" (mal nommé - devrait être 0 écran?). Créer plus de n fenêtres sur un Mac de fenêtre de N est intéressant-en ce que le fait d'appeler "Windows Fullscreen" plusieurs fois va-t-il basculer les fenêtres QMainWindows en mode plein écran un à la fois?!

encore plus intéressant est ce qui se passe sur une machine OS X multi-moniteurs quand vous faites ceci: "ajouter fenêtre" jusqu'à ce que vous ayez autant de fenêtres que d'écrans. "Windows Go To Screens (ancienne méthode)" enverra chaque fenêtre en haut à gauche de chaque moniteur. "Windows Fullscreen" fera passer toutes les fenêtres en plein écran sur tous les moniteurs. "Supprimer fenêtre" jusqu'à ce que vous avez seulement 1 la fenêtre de gauche. Puis "Windows Non-FullScreen", et vous obtiendrez une surprise intéressante. Allez au centre de contrôle pour voir ce qui se passe.

quelqu'un Peut-il me dire quel est le RIGHT façon de le faire est? J'ai regardé dans les exemples de Qt5 - il y a l'application de joueur qui semble être complètement cassé (il peut jouer une vidéo en mode plein écran une fois, et puis les jeux suivants sont dans une fenêtre de bureau séparée), le sous-jeu maximise seulement à un seul écran, et aucun de les autres exemples semblent utiliser le mode plein écran, et certainement pas sur plusieurs moniteurs.

20
demandé sur Ted Middleton 2015-05-08 02:25:17

1 réponses

une façon de le faire en Qt5 est d'utiliser QWindow::setScreen pour définir l'écran sur lequel la fenêtre doit être affichée. QWidget a un windowHandle() qui renvoie le pointeur à QWindow. Donc vous pouvez obtenir ce pointeur pour chaque fenêtre et mettre un écran différent.

Voici comment afficher votre widget dans le dernier écran en mode plein écran:

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

Ou dans le deuxième écran :

QWidget * widget = new QWidget();
widget->show();
widget->windowHandle()->setScreen(qApp->screens()[1]);
widget->showFullScreen();
8
répondu Nejat 2015-06-02 13:26:16