[英]Centering a square qWidget in qt
我正在嘗試使用最新版本的Qt解決圖形問題。 下圖顯示了到目前為止我能做的事情,我將用它來解釋預期的結果。
我使用的是主要的垂直布局,並且在該布局的最大窗口小部件中,只有一個孩子的水平布局是:正方形窗口小部件。 預期的行為當然是使方形小部件水平居中並占用最大可用空間。 不需要使用相同的布局配置,但是界面的外觀應該相同。
上面的圖像是通過以下方式獲得的:為方形小部件設置垂直和水平方向的QSizePolicy的minimumExpanding,並通過以下代碼將其強制為方形:
void SquareWidget::resizeEvent(QResizeEvent *event) {
//This is an override to the QWidget method
QSize s = size();
if (s.height()<s.width()) {
resize(s.height(), s.height());
} else {
resize(s.width(), s.width());
}
return;
}
在嘗試解決此問題時,我瀏覽了該網站上的一些文檔,但找不到關於如何執行兩項任務的明確答案。
第一個問題:如何使小部件方形並保持其長寬比?
有人說,heightForWidth()方法在較新版本的qt中不起作用,經過測試后,它對我也不起作用。 另一方面,上面對resizeEvent的覆蓋會導致遞歸,因為有對resize()的調用(據我所知,布局應處理調整大小)。
第二個問題:如何使正方形居中?
我嘗試使用布局對齊屬性(水平和垂直居中),但它們導致小部件尺寸不可變。
也許我對Qt如何處理小部件放置不了解。 任何建議或澄清將不勝感激。
您可以使用QGridLayout來實現 。
請參閱隨附的代碼。
主窗口
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MyWidget final : public QWidget
{
Q_OBJECT
protected:
virtual void resizeEvent(QResizeEvent * event) override;
};
class MainWindow final : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow() = default;
};
#endif // MAINWINDOW_H
主窗口
#include "mainwindow.h"
#include <QGridLayout>
#include <QLabel>
#include <QResizeEvent>
#include <QSpacerItem>
void MyWidget::resizeEvent(QResizeEvent * event)
{
event->accept();
const QSize current_size = size();
const int min = std::min(current_size.width(), current_size.height());
resize(min, min);
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
auto main_widget = new QWidget;
auto header = new QLabel("Hello World");
auto center_widget = new MyWidget;
auto footer = new QLabel("Good bye World");
auto spacer_left = new QSpacerItem(10, 10, QSizePolicy::Expanding);
auto spacer_right = new QSpacerItem(10, 10, QSizePolicy::Expanding);
auto grid_layout = new QGridLayout(main_widget);
auto center_palette = center_widget->palette();
center_palette.setColor(QPalette::Background, Qt::blue);
center_widget->setAutoFillBackground(true);
center_widget->setPalette(center_palette);
grid_layout->addWidget(header, 0, 1);
grid_layout->addItem(spacer_left, 1, 0);
grid_layout->addWidget(center_widget, 1, 1);
grid_layout->addItem(spacer_right, 1, 2);
grid_layout->addWidget(footer, 2, 1);
header->setAlignment(Qt::AlignCenter);
footer->setAlignment(Qt::AlignCenter);
setCentralWidget(main_widget);
}
與其嘗試使小部件保持其自身的方形和居中,不如將其重新放置並在父小部件類型中放置所需的邏輯可能更簡單。
所以,類似...
class keep_child_square_and_centred: public QWidget {
using super = QWidget;
public:
explicit keep_child_square_and_centred (QWidget *parent = nullptr)
: super(parent)
, m_widget(nullptr)
{}
virtual void set_widget (QWidget *widget)
{
if ((m_widget = widget))
m_widget->setParent(this);
}
virtual QSize sizeHint () const override
{
return(m_widget ? m_widget->sizeHint() : super::sizeHint());
}
protected:
virtual void resizeEvent (QResizeEvent *event) override
{
super::resizeEvent(event);
fixup();
}
private:
void fixup ()
{
if (m_widget) {
QRect r(QPoint(), QSize(height(), height()));
r.moveCenter(rect().center());
m_widget->setGeometry(r);
}
}
QWidget *m_widget;
};
然后用作...
keep_child_square_and_centred w;
SquareWidget sq;
w.set_widget(&sq);
如果父級處於布局中,則可能仍需要進行一些設置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.