2015-05-07 8 views
18

Ich habe ein Windows & Mac-Programm, das auf mehreren Monitoren in den Vollbildmodus wechselt. In Qt 4 scheint es (ich kann keine explizite Dokumentation finden, wie dies zu tun ist), wie die "richtige" Art und Weise dies zu tun ist, indem N QMainWindow für die N Monitore auf der Maschine, QWidget::move() auf die N Monitor oben links x, y-Koordinaten und dann QWidget::setWindowState(Qt::WindowFullScreen) aufrufen. Ich weiß nicht, ob das die richtige Sache ist - ich kann nirgendwo Dokumentation oder Beispiele finden, die das in Qt tun.In Qt 5, was ist der richtige Weg, um Multi-Monitor-Vollbild-QWidget-Fenster anzuzeigen?

Das scheint in Qt 5.4.1, besonders unter Windows 7, "kaputt" zu sein (wenn es überhaupt die richtige Sache war). Ich versuche immer noch, das Problem zu isolieren, aber es scheint so wie die QMainWindow s fallen aus dem Vollbildmodus.

Nur damit ich klar darüber bin, was ist der richtige Weg, dies zu tun? Ich fand this Forumsbeitrag, der darauf hindeutet, dass ich die QScreen auf die zugrunde liegenden QWindow Objekte setzen sollte, die von der QMainWindow s gehalten werden, aber das scheint nicht in meinen Tests zu arbeiten. Hier ist ein Beispiel-Programm, das ich schrieb:

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

Als ich dieses Programm ausführen Auf OS X macht die Funktion "Windows Go To Screens" nichts - keines der Fenster bewegt sich. Auch der "Windows Go To Primary Screen" (schlecht benannt - sollte 0 Bildschirm sein?). Erstellen von mehr als N Fenstern in einem N-Fenster Mac ist interessant - in diesem Fall wird "Windows Fullscreen" mehrmals aufrufen, um die QMainWindows einzeln in den Vollbildmodus zu schalten ?!

Noch interessanter ist, was passiert auf einem Multi-Monitor OS X-Rechner, wenn Sie dies tun: "Add Window", bis Sie so viele Fenster wie angezeigt haben. "Windows Go To Screens (alte Methode)" wird jedes Fenster an die obere linke Seite jedes Monitors senden. Mit "Windows Fullscreen" werden alle Fenster auf allen Monitoren bildschirmfüllend dargestellt. "Fenster entfernen", bis nur noch 1 Fenster übrig ist. Dann "Windows Non-FullScreen", und Sie werden eine interessante Überraschung bekommen. Gehe in die Missionskontrolle, um zu sehen, was vor sich geht.

Kann mir jemand sagen, was die RICHTIG Weg dies zu tun ist? Ich habe mir die Qt5-Beispiele angeschaut - da scheint die Player-Anwendung völlig kaputt zu sein (sie kann ein Video einmal im Vollbildmodus abspielen, und nachfolgende Spiele befinden sich in einem separaten Desktop-Fenster), maximiert das Unterspiel nur ein einziges Display, und keines der anderen Beispiele scheint den Vollbildmodus zu verwenden, und schon gar nicht mehrere Monitore.

Antwort

6

Eine Möglichkeit, dies in Qt5 zu tun, ist die Verwendung von QWindow::setScreen, um den Bildschirm einzustellen, auf dem das Fenster angezeigt werden soll. QWidget hat eine windowHandle(), die den Zeiger auf die QWindow zurückgibt. So können Sie diesen Zeiger für jedes Fenster erhalten und einen anderen Bildschirm einstellen.

Hier ist, wie das Widget in dem letzten Bildschirm zu zeigen, im Vollbildmodus:

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

Oder im zweiten Bildschirm:

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