簡體   English   中英

在qt中將方形qWidget居中

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM