Pregunta

¿Cómo es posible mantener la relación de aspecto de los widgets en Qt y qué hay de centrar el widget?

¿Fue útil?

Solución

No tiene que implementar su propio administrador de diseño. Puede hacerlo heredando QWidget y reimplementando

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

para mantenerse cuadrado. Sin embargo, heightForWidth () no funciona en ventanas de nivel superior en X11, ya que aparentemente el protocolo X11 no lo admite. En cuanto al centrado, puede pasar Qt :: AlignCenter como el tercer parámetro de QBoxLayout :: addWidget () o el quinto parámetro de QGridLayout :: addWidget () .

Nota: al menos en las versiones más recientes de Qt, QWidget ya no tiene heightForWidth o widthForHeight (por lo que no se pueden anular) y, por lo tanto, setWidthForHeight (true) o setHeightForWidth (true) solo tiene un efecto para los descendientes de QGraphicsLayout .

Otros consejos

La respuesta correcta es crear su administrador de diseño personalizado. Eso es posible subclasificando QLayout .

Métodos para implementar al subclasificar QLayout

  
void addItem (elemento QLayoutItem *);
  
Agrega un elemento al diseño.
  
int count () const;
  
Devuelve el recuento de elementos.
  
QLayoutItem * itemAt (int index) const;
  
Devuelve la referencia del elemento en el índice o 0 si no hay ninguno.
  
QLayoutItem * takeAt (int index);
  
Toma y devuelve el elemento del diseño del índice o devuelve 0 si no hay ninguno.
  
Qt :: Orientations expansionDirections () const;
  
Devuelve los diseños expandiendo las direcciones.
  
bool hasHeightForWidth () const;
  
Indica si el diseño maneja la altura para el cálculo del ancho.
  
QSize minimumSize () const;
  
Devuelve el tamaño mínimo de diseño.
  
void setGeometry (const QRect & amp; rect);
  
Establece la geometría del diseño y los elementos dentro de él. Aquí debe mantener la relación de aspecto y centrarla.
  
QSize sizeHint () const;
  
Devuelve el tamaño preferido para el diseño.

Lecturas adicionales

Llamar a resize () desde resizeEvent () nunca me ha funcionado bien; en el mejor de los casos, provocará parpadeos cuando la ventana se redimensione dos veces (como usted ), en el peor de los casos, un bucle infinito.

Creo que el " correcto " La forma de mantener una relación de aspecto fija es crear un diseño personalizado. Tendrá que anular solo dos métodos, QLayoutItem :: hasHeightForWidth () y QLayoutItem :: heightForWidth () .

En mi caso, anular heightForWidth () no funciona. Y, para alguien, podría ser útil obtener un ejemplo de uso del evento de cambio de tamaño.

En la primera subclase qObject para crear filtro. Más información sobre los filtros de eventos.

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

Entonces función eventFilter. Su código debe definirse fuera de la definición de FilterObject para evitar advertencias. Gracias a esta respuesta.

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

Y luego, en el código principal, cree FilterObject y configúrelo como detector de EventFilter para el objeto de destino. Gracias a esta respuesta.

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

Ahora el filtro recibirá todos los eventos de targetWidget y establecerá la altura correcta en el evento de cambio de tamaño.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top