2011-08-24 13 views
5

Sto avendo tutti i tipi di problemi di dimensioni con Qt. Sto creando i miei propri widget e utilizzando layout diversi (in genere, ho bisogno del mio per farli funzionare correttamente senza passare ore sui "potenti" layout predefiniti ... che non espongono le cose come previsto.)Cosa rende un widget Qt e il suo layout si comportano correttamente (rispetto alle sue dimensioni)?

Una volta che ho finito con un widget e il suo layout, però, non funziona bene. La dimensione non viene impostata correttamente, a meno che non chiami il numero widget->resize(1, 1); che alla fine impone un "ridimensionamento" e rende il widget corretto (ovvero ricalcola la geometria). Anche la chiamata updateGeometry() non ha alcun effetto.

Questo è un problema terribile quando il resize() deve essere chiamato sul widget genitore (schifo!) E da quello che sto leggendo non dovrebbe essere necessario se i layout sono stati programmati correttamente.

C'è un campione che funziona e non è lungo diverse migliaia di righe, oppure Qt richiede diverse migliaia di linee per far funzionare tutto perfettamente, anche il widget più semplice?

Quali sono le funzioni minime da chiamare per rendere un widget & il suo layout funziona in una sola volta?

Grazie. Alexis

P.S. Ho provato a implementare lo sizeHint(), minimumSize(), maximumSize(), altri che mi mancano? Speravo che sarebbe stato abbastanza. Ovviamente, ho anche implementato il setGeometry() sul layout per ridimensionare i bambini in modo appropriato.

--- aggiunta 1

C'è un'immagine campione con un layout che chiaramente non è disponibile come in Qt. Il posizionamento, le funzioni e i colori dei diversi tasti sono basati su XML e funzionano per qualsiasi tastiera del mondo.

On screen keyboard

(nota, questo campione non mostra il tasto Invio visualizzato su due righe e più ampia di sotto di quanto in alto, più o meno, non è fattibile a tutti con i layout regolari; naturalmente, funziona con la mia versione.)

--- chiarimento

io non sono troppo sicuro di come descrivere meglio il problema. Stavo pensando di scrivere un widget di test per vedere come posso riprodurre il problema e poi postarlo e risolverlo. 8-)

La funzione di layout predefinita utilizzata dai layout Qt interni richiede molta codifica. Vorrei evitare di dover copiare/incollare tutto ciò perché, per la manutenzione, rende quasi impossibile.

--- scoperte di oggi

come ho bisogno di modificare uno dei widget, ho deciso di aggiungere un VBoxLayout e farlo funzionare.

In realtà ho trovato il problema ... Uno dei widget nel mio albero è un QScrollArea e restituisce sizeHint() (-1, -1). Non esattamente quello che mi aspetterei ma ... qualunque cosa tu abbia messo dentro quel widget è meglio sapere come calcolarne la larghezza e l'altezza altrimenti ... fallisce.

Guardando il codice da vicino, ho potuto effettivamente calcolare la larghezza utilizzando la più ampia larghezza trovato. Una volta che l'ho usato, il widget apparirà (e in effetti si ridimensionerà come le cose cambiano nella lista, un po 'figo.)

Detto questo, il mio precedente commento sull'avere un albero di widget che si auto-ridimensiona da solo si erge. Dalla radice fino ai genitori delle foglie nell'albero, tutti questi widget avranno bisogno di un layout valido. Una volta ho aggiunto uno nel widget in alto, ridimensionato se stesso e i suoi figli correttamente (beh ... nel mio caso fino al QScrollArea, il resto richiedeva un ridimensionamento dal basso verso l'alto. Divertente come funziona!)

--- ah! ah! momento (o: cosa trovi leggendo il codice di implementazione!)

Oggi ho riscontrato un altro problema che richiedeva solo la chiamata corretta ... Non riuscivo a trovare nulla che valesse la pena nella documentazione.

Tutti gli oggetti hanno un layout ora, ma un determinato genitore non viene ridimensionato correttamente. Semplice semplice.

ho avuto una chiamata al genitore come segue:

// changes to the children are changing the geometry 
parentWidget()->updateGeometry(); 

Già. I documenti dicono che è quello che devi fare. Nulla accade affatto con quella chiamata. Non ho idea di cosa dovrebbe fare, non ho guardato a quella funzione. Non ha mai fatto nulla per me comunque.

Allora ... ho guardato il layout per cercare di capire come sarebbe andata a inviare le informazioni su/giù. Non ho visto molto tranne che per un commento interessante:

// will trigger resize 

Questo si dice della modalità SetFixedSize. Per raggiungere questa funzione è necessario creare il layout per l'aggiornamento. Ah! Sì ... il layout, non il widget genitore ... proviamo invece:

parentWidget()->layout()->update(); 

E voilà! Si ridimensiona correttamente in tutti i casi che ho. Abbastanza incredibile che il widget updateGeometry() non attivi lo stesso effetto ...

+2

Che cosa è che si sta cercando di realizzare che il sistema di layout integrato non può fare per te? È difficile rispondere a una domanda che ti sarà utile quando si riduce sostanzialmente a "come faccio a far funzionare le cose?" – Chris

+0

Per le domande GUI/Layout, inclusa una schermata con annotazioni può essere di grande aiuto. Non c'è carenza di persone qui che amano capire le cose quando hanno informazioni solide :) –

+0

se non hai problemi con il tuo codice allora puoi condividerlo su www.ideone.com: D – blueskin

risposta

1

Questo non ti aiuterà con il tuo problema immediato ma volevo mostrarti una tastiera che ho realizzato usando layout e pulsanti standard. Non è perfetto e ancora non ti aiuterà con una chiave di invio che si estende su due righe, ma non è male. È ridimensionabile anche ridimensionando la finestra, anche se non sono sicuro se ciò sarà evidente dalle immagini qui sotto come SO potrebbe ridimensionarle. (È possibile visualizzare le immagini reali con la loro apertura nella propria scheda)

enter image description here

enter image description here

In ogni caso, questo è stato fatto utilizzando solo Designer Qt senza codifica manuale. Consiste in un layout verticale di livello superiore con 5 layout orizzontali. I pulsanti vengono quindi inseriti in uno dei 5 layout orizzontali. La dimensione dei tasti può essere controllata impostando i criteri di dimensione orizzontale e verticale su "ignorati" per la maggior parte dei pulsanti e quindi su "minimo" orizzontale per i pulsanti che si desidera aumentare. Le cose possono essere ottimizzate impostando le restrizioni minime e massime sui pulsanti. Se ridimensionati, i pulsanti non manterranno le proporzioni relative, ma probabilmente richiederebbero una programmazione personalizzata.

Lo styling nel tuo esempio potrebbe essere approssimato piuttosto bene con i fogli di stile CSS e immagini di sfondo.Ancora non è un piccolo sforzo, ma dovresti essere in grado di ottenere la maggior parte del modo lì senza layout e pulsanti personalizzati.

+1

Sì. Ci sono molti problemi con il QSS. Funziona a cascata solo sulla creazione dei widget. Dopo di ciò, si dimentica totalmente dei genitori. Quindi non è così pratico. Detto questo, uso il QSS per i colori, i bordi, la dimensione del font, le immagini ... Ora, riflettendo su questo, mi chiedo se il mio problema potrebbe essere in realtà perché tutti gli antenati non includono un layout. Penso di aver letto da qualche parte che per i layout di lavorare bene ne hai bisogno ovunque. Infine, nel mio caso la tastiera può essere commutata su tutti i tipi di layout. Ad esempio, potrei cambiarlo in una tastiera Kania o francese. –

2

Anche se è possibile fare ciò che si desidera, sembra che i problemi che si verificano siano perché si sta utilizzando Qt in un modo che non è destinato a essere utilizzato. Perché hai bisogno di widget separati per ogni tasto rappresentato sulla tastiera?

vedo due opzioni, che sono entrambi meglio, in qualche modo:

  1. Utilizzare QGraphicsScene e QGraphicsView.
  2. Un singolo widget personalizzato che utilizza il disegno personalizzato per visualizzare la tastiera (e utilizza probabilmente il passaggio del mouse per i suggerimenti).

La prima opzione è probabilmente migliore. Le tue chiavi potrebbero quindi essere rappresentate da QGraphicsSimpleTextItem o anche da un QGraphicsSvgItem. Fornisce inoltre una serie di layout standard oppure è possibile scegliere tra write your own layout. Per impostazione predefinita è possibile utilizzare keyPressEvent o mouseReleaseEvent per rispondere alle interazioni dell'utente.

Consiglio vivamente di dare un'occhiata a QGraphicsView examples per avere un'idea di cosa è possibile fare.

Se si va al secondo percorso avrete bisogno di registrare le diverse posizioni chiave in modo da poter rispondere di conseguenza come l'utente sposta il mouse, clic, ecc

+0

Dovrei rendere tutto a mano in questo caso? Con i PushButtons ottengo il rendering gratuitamente e l'evento cliccato() ... Anche la mia tastiera era un esempio, il problema che avevo era in una lista in cui la catena di layout si rompe a causa di QScrollArea (cioè sotto il QScrollArea il la dimensione non è limitata in altezza, vogliamo ridimensionare il widget all'interno di QScrollArea il più alto possibile! Ma il QScrollArea deve essere una dimensione ragionevole per lo scopo.) –

+0

Post modificato per commenti. –

Problemi correlati