【问题标题】:Centering a square qWidget in qt在 qt 中将方形 qWidget 居中
【发布时间】:2017-04-09 12:27:28
【问题描述】:

我正在尝试使用最新版本的 Qt 解决图形问题。下图显示了我到目前为止所取得的成果,我将用它来解释预期的结果。

我正在使用主要的垂直布局,并且在布局的最大小部件中,有一个只有一个子元素的水平布局:方形小部件。预期的行为当然是让方形小部件水平居中并占用最大的可用空间。不需要使用相同的布局配置,但界面的外观应该相同。

上面的图像是通过将垂直和水平方向的 QSizePolicy 设置为方形小部件并使用以下代码强制它为方形来获得的:

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

在尝试解决此问题时,我浏览了该网站上的一些答案的文档,但找不到有关如何执行两项任务的明确答案。

第一个问题:如何使小部件呈正方形并保持其纵横比?

In this question

据说heightForWidth()方法在较新版本的qt中不起作用,经过测试对我也不起作用。另一方面,上面对 resizeEvent 的覆盖会导致递归,因为调用了 resize() (据我了解,布局应该处理调整大小)。

第二个问题:如何使正方形居中?

我尝试使用布局对齐属性(水平和垂直居中),但它们会导致小部件大小不可变。

也许我不了解 Qt 如何处理小部件放置。任何建议或澄清将不胜感激。

【问题讨论】:

  • 关于“heightForWidth 不起作用”,请查看答案的日期:8 年前。这些天 QWidget 有它:doc.qt.io/qt-5/qwidget.html#hasHeightForWidth
  • @peppe 谢谢你的信息。如果我使用 heightforwidth 方法,那不会导致居中问题吗?

标签: c++ qt c++11


【解决方案1】:

您可以通过QGridLayout 来完成。

请查看附件代码。

mainwindow.h

#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

mainwindow.cpp

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

Please see the result here

【讨论】:

    【解决方案2】:

    与其试图让小部件保持正方形和居中,不如重新设置它的父级并将所需的逻辑放入父小部件类型中可能更简单。

    所以,类似...

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

    如果父级在布局中,您可能仍需要尝试一些设置。

    【讨论】:

      猜你喜欢
      • 2013-08-20
      • 2018-01-10
      • 1970-01-01
      • 2017-07-08
      • 1970-01-01
      • 2012-08-13
      • 2021-08-27
      • 2011-06-23
      相关资源
      最近更新 更多