2017-04-09 384 views
0

我正在嘗試使用最新版本的Qt解決圖形問題。下面的圖片顯示了我迄今爲止獲得的成果,我將用它來解釋預期結果。以qt爲中心的正方形qWidget

The result of my work

我使用一個主垂直佈局和佈局中最大的窗口小部件內有一個橫向佈局只有一個孩子:正方形的小工具。預期的行爲當然是將方形小部件水平居中並佔用最大的可用空間。不需要使用相同的佈局配置,但接口的外觀應該相同。

上面已經通過設置minimumExpanding的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如何處理小部件的位置。任何建議或澄清將不勝感激。

+0

關於 「heightForWidth不起作用」,看看答案的日期:8年前。現在QWidget有它:https://doc.qt.io/qt-5/qwidget.html#hasHeightForWidth – peppe

+0

@peppe感謝您的信息。如果我使用heightforwidth方法,不會導致集中問題嗎? – ProTom

回答

0

而不是試圖讓小部件,以保持自身廣場和中心可能是簡單的重新設置父級,並把所需的邏輯父控件類型。

所以,像...

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

您可能還需要如果家長在佈局雖然玩弄一些設置。

+0

這工作得很好,謝謝 – ProTom

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 

主窗口。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