Domanda

Come è possibile mantenere le proporzioni dei widget in Qt e che dire del centrare il widget?

È stato utile?

Soluzione

Non è necessario implementare il proprio gestore di layout. Puoi fare con l'eredità di QWidget e la reimplementazione

int QWidget::heightForWidth( int w ) { return w; }

per rimanere quadrati. Tuttavia, heightForWidth () non funziona su finestre di livello superiore su X11, poiché apparentemente il protocollo X11 non lo supporta. Per quanto riguarda il centraggio, è possibile passare Qt :: AlignCenter come terzo parametro di QBoxLayout :: addWidget () o il quinto parametro di QGridLayout :: addWidget () .

Nota: almeno nelle versioni più recenti di Qt, QWidget non ha più heightForWidth o widthForHeight (quindi non possono essere sostituiti) , e quindi setWidthForHeight (true) o setHeightForWidth (true) ha effetto solo per i discendenti di QGraphicsLayout .

Altri suggerimenti

La risposta giusta è creare il tuo gestore di layout personalizzato. Ciò è possibile effettuando la sottoclasse di QLayout .

Metodi da implementare durante la sottoclasse di QLayout

  
void addItem (elemento QLayoutItem *);
  
Aggiunge l'elemento al layout.
  
int count () const;
  
Restituisce il conteggio degli articoli.
  
QLayoutItem * itemAt (int index) const;
  
Restituisce il riferimento dell'oggetto all'indice o 0 se non ce n'è.
  
QLayoutItem * takeAt (int index);
  
Prende e restituisce l'elemento dal layout dall'indice o restituisce 0 se non ce n'è.
  
Qt :: Orientations expandingDirections () const;
  
Restituisce le direzioni espandendo i layout.
  
bool hasHeightForWidth () const;
  
Indica se il layout gestisce l'altezza per il calcolo della larghezza.
  
QSize minimumSize () const;
  
Restituisce la dimensione minima del layout.
  
void setGeometry (const QRect & amp; rect);
  
Imposta la geometria del layout e gli elementi al suo interno. Qui devi mantenere le proporzioni e centrare.
  
QSize sizeHint () const;
  
Restituisce la dimensione preferita per il layout.

Ulteriori letture

Chiamare resize () dall'interno di resizeEvent () non ha mai funzionato bene per me - nella migliore delle ipotesi causerà sfarfallio poiché la finestra viene ridimensionata due volte (come hai fatto ), nel peggiore dei casi un ciclo infinito.

Penso che " corretto " il modo per mantenere le proporzioni fisse consiste nel creare un layout personalizzato. Dovrai sovrascrivere solo due metodi, QLayoutItem :: hasHeightForWidth () e QLayoutItem :: heightForWidth () .

Nel mio caso la sostituzione di heightForWidth () non funziona. E, per qualcuno, potrebbe essere utile ottenere un esempio funzionante dell'uso dell'evento resize.

Alla prima sottoclasse qObject per creare il filtro. Ulteriori informazioni sui filtri degli eventi.

class FilterObject:public QObject{
public:
    QWidget *target = nullptr;//it holds a pointer to target object
    int goalHeight=0;
    FilterObject(QObject *parent=nullptr):QObject(parent){}//uses QObject constructor
    bool eventFilter(QObject *watched, QEvent *event) override;//and overrides eventFilter function
};

Quindi la funzione eventFilter. Il suo codice deve essere definito al di fuori della definizione FilterObject per evitare avvisi. Grazie a questa risposta.

bool FilterObject::eventFilter(QObject *watched, QEvent *event) {
    if(watched!=target){//checks for correct target object.
        return false;
    }
    if(event->type()!=QEvent::Resize){//and correct event
        return false;
    }

    QResizeEvent *resEvent = static_cast<QResizeEvent*>(event);//then sets correct event type

    goalHeight = 7*resEvent->size().width()/16;//calculates height, 7/16 of width in my case
    if(target->height()!=goalHeight){
        target->setFixedHeight(goalHeight);
    }

    return true;
};

Quindi, nel codice principale, creare FilterObject e impostarlo come listener EventFilter sull'oggetto target. Grazie a questa risposta.

FilterObject *filter = new FilterObject();
QWidget *targetWidget = new QWidget();//let it be target object
filter->target=targetWidget;
targetWidget->installEventFilter(filter);

Ora il filtro riceverà tutti gli eventi targetWidget e imposterà l'altezza corretta all'evento di ridimensionamento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top