在qt中,我们有时需要保持控件长宽比固定,但是很少能找到能够良好运行的代码,重载resizeEvent
函数效果都不太好
在github上搜索RatioWidget
找到了一个可以运行的:AspectRatioWidget类,基本思想就是通过控制在layout
的QSpacerItem
的大小来控制中心的控件的长宽比,基于此做了一个小案例供大家参考:
#ifndef ASPECTRATIOWIDGET_H
#define ASPECTRATIOWIDGET_H
#include <QWidget>
#include <QBoxLayout>
class AspectRatioWidget : public QWidget
{
public:
AspectRatioWidget(QWidget *widget, float width, float height, QWidget *parent = 0);
void resizeEvent(QResizeEvent *event);
private:
QBoxLayout *layout;
float arWidth;
float arHeight;
};
#endif // ASPECTRATIOWIDGET_H
#include "aspectratiowidget.h"
#include <QResizeEvent>
AspectRatioWidget::AspectRatioWidget(QWidget *widget, float width, float height, QWidget *parent) :
QWidget(parent),
arWidth(width),
arHeight(height)
{
layout = new QBoxLayout(QBoxLayout::LeftToRight, this);
layout->addItem(new QSpacerItem(0, 0));
layout->addWidget(widget);
layout->addItem(new QSpacerItem(0, 0));
}
void AspectRatioWidget::resizeEvent(QResizeEvent *event)
{
float thisAspectRatio = (float)event->size().width() / event->size().height();
int widgetStretch, outerStretch;
if (thisAspectRatio > (arWidth/arHeight))
{
// 太宽了 --> 调整为水平布局 --> 在左右两侧的弹簧将控件宽度挤回正常比例
layout->setDirection(QBoxLayout::LeftToRight);
widgetStretch = height() * (arWidth/arHeight);
outerStretch = (width() - widgetStretch) / 2 + 0.5;
}
else
{
// 太高了 --> 调整为垂直布局 --> 在上下两侧的弹簧将控件高度挤回正常比例
layout->setDirection(QBoxLayout::TopToBottom);
widgetStretch = width() * (arHeight/arWidth);
outerStretch = (height() - widgetStretch) / 2 + 0.5;
}
layout->setStretch(0, outerStretch);
layout->setStretch(1, widgetStretch);
layout->setStretch(2, outerStretch);
}
基于这个类在MainWindow
中进行实例化,这里我们使用水平布局,左边加一个label,右边实例化上面的AspectRatioWidget
类,内部也填充一个label,将所有控件的父控件都设置为ui->centralwidget
:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QLabel *label_1 = new QLabel("Label 1", ui->centralwidget);
QLabel *label_2 = new QLabel("Label 2", ui->centralwidget);
QHBoxLayout *horizontalLayout = new QHBoxLayout(ui->centralwidget);
ui->centralwidget->setLayout(horizontalLayout);
horizontalLayout->addWidget(label_1,1);
horizontalLayout->addWidget(new AspectRatioWidget(label_2, 2, 1, ui->centralwidget),1);
label_1->setStyleSheet("background-color: blue;");
label_2->setStyleSheet("background-color: black;");
}
MainWindow::~MainWindow()
{
delete ui;
}
这就大功告成了,运行效果是这样的:
非常的丝滑和优雅,如果对你有所帮助就请点个赞再走吧 🤖 !