Pergunta

Como é que é possível manter os widgets proporção em Qt e que sobre centrar o widget?

Foi útil?

Solução

Você não tem que implementar seu próprio gerenciador de layout. Você pode fazer com herdar QWidget e reimplementar

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

para ficar quadrado. No entanto, heightForWidth() não funciona em janelas de topo no X11, já que, aparentemente, o protocolo X11 não suporta isso. Quanto a centralização, você pode passar Qt::AlignCenter como o terceiro parâmetro de QBoxLayout::addWidget() ou o quinto parâmetro de QGridLayout::addWidget().

Nota: Nas versões mais recentes do Qt, pelo menos, QWidget não tem o heightForWidth ou widthForHeight mais (para que eles não podem ser substituídas), e, portanto, setWidthForHeight(true) ou setHeightForWidth(true) só tem um efeito para descendentes de QGraphicsLayout .

Outras dicas

A resposta certa é criar seu gerenciador de layout personalizado. Isso é possível por subclasse QLayout .

Métodos de implementar quando subclasses QLayout

vazio addItem (* item de QLayoutItem);
artigo acrescenta ao layout.
int count () const;
Retorna a contagem item.
QLayoutItem * itemAt (int index) const;
referência item de devolução no índice ou 0 se não há nenhum.
QLayoutItem * takeAt (índice int);
Toma e retorna item do esquema de índice ou retorna 0 se não há nenhuma.
Qt :: Orientações expandingDirections () const;
Retorna os layouts expansão direções.
bool hasHeightForWidth () const;
Indica se a altura alças de layout para o cálculo de largura.
QSize MinimumSize () const;
retorna o tamanho layouts mínimo.
vazio setGeometry (const QRect & rect);
Define a geometria do layout e os itens dentro dela. Aqui você tem que manter a proporção e fazer a centralização.
QSize sizeHint () const;
Retorna o tamanho preferido para o layout.

Leitura

Chamando resize() de dentro resizeEvent() nunca trabalhou bem para mim - na melhor das hipóteses ele vai causar cintilação como a janela é redimensionada duas vezes (como você tem), na pior das hipóteses um loop infinito

.

Eu acho que a maneira "correta" para manter uma proporção fixa é criar um layout personalizado. Você terá que substituir apenas dois métodos, QLayoutItem::hasHeightForWidth() e QLayoutItem::heightForWidth().

No meu caso substituindo heightForWidth () não funciona. E, para alguém, que poderia ser útil para obter exemplo de trabalho de usar evento de redimensionamento.

Na primeira subclasse QObject para criar filtro. mais sobre 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
};

Função Então EventFilter. É o código deve ser definido fora da definição FilterObject para evitar aviso. Graças a esta resposta.

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

E, em seguida, no código principal criar FilterObject e defini-lo como EventFilter ouvinte objeto de destino. Graças a esta resposta.

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

Agora filtro irá receber todos os eventos do targetWidget e conjunto altura correta no evento de redimensionamento.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top