2015-05-07 10 views
18

Possiedo un programma Windows & Mac che passa in modalità a schermo intero su più monitor. In Qt 4, sembra (non riesco a trovare la documentazione esplicita su come farlo) come il modo "corretto" per farlo è creando N QMainWindow per i monitor N sulla macchina, chiamando QWidget::move() in N monitor in alto a sinistra x, coordinate ye quindi chiamate QWidget::setWindowState(Qt::WindowFullScreen). Non so se questa è la cosa giusta da fare - di nuovo, non riesco a trovare alcuna documentazione o esempi da nessuna parte che facciano questo in Qt.In Qt 5, qual è il modo giusto per mostrare finestre QWidget a schermo intero a schermo multiplo?

Questo sembra essere "rotto" (se fosse mai stata la cosa giusta da fare in primo luogo) in Qt 5.4.1, specialmente su Windows 7. Sto ancora cercando di isolare il problema, ma sembra come il QMainWindow s stanno abbandonando la modalità a schermo intero.

Solo così sono chiaro su questo, qual è il modo giusto per farlo? Ho trovato il post sul forum this che sembra suggerire che dovrei impostare QScreen sugli oggetti QWindow sottostanti che sono detenuti dal QMainWindow s, ma questo non sembra funzionare nei miei test. Ecco un esempio di programma che ho scritto:

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

Quando eseguo questo programma su OS X, la funzione "Windows Go To Screens" non fa nulla, nessuna delle finestre si sposta. Neanche "Windows Go To Primary Screen" (mal chiamato) dovrebbe essere 0 schermo?). Creare più di N finestre su una finestra N Mac è interessante: in tal caso, la chiamata a "Schermo intero Windows" diverse volte commuterà effettivamente QMainWindows in modalità a schermo intero una alla volta ?!

Ancora più interessante è ciò che accade su una macchina OS X multi-monitor quando si esegue questa operazione: "Aggiungi finestra" finché non si dispone di un numero di finestre pari a quello visualizzato. "Windows Go To Screens (vecchio metodo)" invierà ogni finestra in alto a sinistra di ciascun monitor. "Windows Fullscreen" farà sì che tutte le finestre vadano a schermo intero su tutti i monitor. "Rimuovi finestra" finché non rimane solo 1 finestra. Quindi "Windows Non-FullScreen", e avrai una sorpresa interessante. Entra in Mission Control per vedere cosa sta succedendo.

Qualcuno può dirmi che cos'è il modo RIGHT? Ho esaminato gli esempi Qt5 - c'è l'applicazione del lettore che sembra essere completamente rotta (può riprodurre un video in modalità a schermo intero una volta, e quindi i giochi successivi sono in una finestra del desktop separata), il gioco secondario si limita a un singolo display e nessuno degli altri esempi sembra utilizzare la modalità a schermo intero e certamente non su più monitor.

risposta

6

Un modo per farlo in Qt5 è utilizzare QWindow::setScreen per impostare lo schermo su cui deve essere visualizzata la finestra. QWidget ha un windowHandle() che restituisce il puntatore allo QWindow. Quindi puoi ottenere quel puntatore per ogni finestra e impostare uno schermo diverso.

Ecco come mostrare il tuo widget in ultima schermata in modalità a schermo intero:

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

O nella seconda schermata:

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