如何在 Qt 中保持小部件的长宽比?
-
19-08-2019 - |
题
如何在 Qt 中保持小部件的纵横比以及使小部件居中怎么样?
解决方案
您不必实现自己的布局管理器。你可以通过继承来做 QWidget
并重新实施
int QWidget::heightForWidth( int w ) { return w; }
保持方形。然而, heightForWidth()
不适用于 X11 上的顶级窗口,因为显然 X11 协议不支持它。至于居中,可以通过 Qt::AlignCenter
作为第三个参数 QBoxLayout::addWidget()
或第五个参数 QGridLayout::addWidget()
.
笔记: 至少在较新版本的 Qt 中,QWidget 没有 heightForWidth
或者 widthForHeight
不再(所以它们不能被覆盖),因此 setWidthForHeight(true)
或者 setHeightForWidth(true)
仅对 QGraphicsLayout 的后代有效.
其他提示
正确的答案是创建自定义布局管理器。这可以通过子类化来实现 布局布局.
子类化 QLayout 时要实现的方法
- 无效addItem(QLayoutItem *项目);
- 将项目添加到布局。
- int count() 常量;
- 返回项目计数。
- QLayoutItem* itemAt(int index) const;
- 返回索引处的项目引用,如果没有则返回 0。
- QLayoutItem* takeAt(int 索引);
- 从索引的布局中获取并返回项目,如果没有则返回 0。
- Qt::Orientations ExpandingDirections() const;
- 返回布局扩展方向。
- bool hasHeightForWidth() const;
- 告知布局是否处理宽度计算的高度。
- QSize 最小尺寸() const;
- 返回布局的最小尺寸。
- void setGeometry(const QRect& rect);
- 设置布局及其内部项目的几何形状。在这里你必须保持纵横比并居中。
- QSize sizeHint() const;
- 返回布局的首选大小。
进一步阅读
调用resize()
从resizeEvent()
内从来没有运作良好,我 - 充其量会造成闪烁的窗口大小的两倍(因为你),在最坏的一个无限循环
我认为“正确”的方式来保持固定的长宽比来创建自定义布局。你必须重写了两个方法,QLayoutItem::hasHeightForWidth()
和QLayoutItem::heightForWidth()
。
在我的情况下重写heightForWidth()不工作。而且,对于一个人,也可能是有帮助的工作得到利用调整事件的例子。
目前第一亚类的QObject创建过滤器。 更多关于事件过滤器。
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
};
然后eventFilter功能。它的代码应该FilterObject定义之外被定义为防止警告。 由于该答案。
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;
};
和然后在主代码创建FilterObject并将其设置为EventFilter侦听到目标对象。 由于该答案。
FilterObject *filter = new FilterObject();
QWidget *targetWidget = new QWidget();//let it be target object
filter->target=targetWidget;
targetWidget->installEventFilter(filter);
现在筛选将接收所有targetWidget的事件,并在resize事件设置正确的高度。