webentwicklung-frage-antwort-db.com.de

Wie pflege ich das Seitenverhältnis von Widgets in Qt?

Wie ist es möglich, das Seitenverhältnis von Widgets in Qt beizubehalten und wie sieht es mit dem Zentrieren des Widgets aus?

31
Bleadof

Sie müssen keinen eigenen Layout-Manager implementieren. Sie können QWidget übernehmen und reimplementieren

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

quadratisch bleiben. heightForWidth() funktioniert jedoch nicht auf Fenstern der obersten Ebene unter X11, da das X11-Protokoll dies offenbar nicht unterstützt. Zur Zentrierung können Sie Qt::AlignCenter als dritten Parameter von QBoxLayout::addWidget() oder den fünften Parameter von QGridLayout::addWidget() übergeben.

Hinweis: In neueren Versionen von Qt hat QWidget nicht mehr die Variable heightForWidth oder widthForHeight (daher können sie nicht überschrieben werden). Daher haben setWidthForHeight(true) oder setHeightForWidth(true)nur Auswirkungen auf QGraphicsLayout .

16

Die richtige Antwort ist, Ihren benutzerdefinierten Layout-Manager zu erstellen. Dies ist durch die Unterklasse QLayout möglich.

Zu implementierende Methoden beim Unterklassen von QLayout

void addItem (QLayoutItem * item);
Fügt Element zum Layout hinzu.
int count () const;
Gibt die Anzahl der Artikel zurück.
QLayoutItem * itemAt (int index) const;
Gibt eine Elementreferenz am Index zurück oder 0, wenn keine vorhanden ist.
QLayoutItem * takeAt (int index);
Nimmt Elemente aus dem Layout aus dem Index und gibt sie zurück oder gibt 0 zurück, wenn keine vorhanden sind.
Qt :: Orientierungen expandDirections () const;
Gibt die Layout-Erweiterungsrichtungen zurück.
bool hasHeightForWidth () const;
Gibt an, ob das Layout die Höhe für die Breitenberechnung berücksichtigt.
QSize minimumSize () const;
Gibt die minimale Größe des Layouts zurück.
void setGeometry (const QRect & rect);
Legt die Geometrie des Layouts und die darin enthaltenen Elemente fest. Hier müssen Sie das Seitenverhältnis beibehalten und die Zentrierung vornehmen.
QSize sizeHint () const;
Gibt die bevorzugte Größe für das Layout zurück.

Lesen Sie weiter

8
Bleadof

Das Aufrufen von resize() von innen aus resizeEvent() hat für mich nie gut funktioniert - im besten Fall wird es flackern, da das Fenster zweimal (wie bei Ihnen) in der Größe verändert wird, im schlimmsten Fall eine Endlosschleife.

Ich denke, der "richtige" Weg, um ein festes Seitenverhältnis aufrechtzuerhalten, besteht darin, ein benutzerdefiniertes Layout zu erstellen. Sie müssen nur zwei Methoden überschreiben, QLayoutItem::hasHeightForWidth() und QLayoutItem::heightForWidth().

5
dF.

In meinem Fall funktioniert das Überschreiben von heightForWidth () nicht. Und für jemanden kann es hilfreich sein, ein funktionierendes Beispiel für die Verwendung des Größenänderungsereignisses zu erhalten.

In der ersten Unterklasse qObject wird ein Filter erstellt. Mehr über Ereignisfilter.

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

Dann die eventFilter-Funktion. Sein Code sollte außerhalb der FilterObject-Definition definiert werden, um Warnungen zu verhindern. Dank dieser Antwort.

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

Erstellen Sie dann im Hauptcode FilterObject und legen Sie es als EventFilter-Listener auf das Zielobjekt fest. Dank dieser Antwort.

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

Der Filter empfängt jetzt alle Ereignisse von targetWidget und legt die korrekte Höhe beim Größenänderungsereignis fest.

0
PolyGlot