2014-06-17 96 views
4

我想在QGroupBox上保留16/9的縱橫比(下面屏幕截圖中的左邊那個)。爲測試我在垂直佈局具有4個groupboxes製成一個簡單的程序,所有的在水平佈局:Qt佈局 - 在調整大小時保持小部件縱橫比

的main.cpp

#include "MainWindow.h" 
#include <QApplication> 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 

    return a.exec(); 
} 

MainWindow.h

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 

namespace Ui { 
class MainWindow; 
} 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 


private: 
    Ui::MainWindow *ui; 
}; 

#endif // MAINWINDOW_H 

MainWindow.cpp

#include "MainWindow.h" 
#include "ui_MainWindow.h" 

#include <QDebug> 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
    qDebug() << "horizontalLayout->hasHeightForWidth: " << ui->horizontalLayout->hasHeightForWidth(); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

MainWindow.ui

<?xml version="1.0" encoding="UTF-8"?> 
<ui version="4.0"> 
<class>MainWindow</class> 
<widget class="QMainWindow" name="MainWindow"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>1000</width> 
    <height>703</height> 
    </rect> 
    </property> 
    <property name="windowTitle"> 
    <string>MainWindow</string> 
    </property> 
    <widget class="QWidget" name="centralWidget"> 
    <layout class="QHBoxLayout" name="horizontalLayout"> 
    <item> 
    <widget class="GroupBoxHFW" name="groupBox_1"> 
     <property name="title"> 
     <string>GroupBox</string> 
     </property> 
    </widget> 
    </item> 
    <item> 
    <layout class="QVBoxLayout" name="verticalLayout"> 
     <item> 
     <widget class="QGroupBox" name="groupBox_2"> 
     <property name="minimumSize"> 
     <size> 
      <width>485</width> 
      <height>204</height> 
     </size> 
     </property> 
     <property name="maximumSize"> 
     <size> 
      <width>485</width> 
      <height>204</height> 
     </size> 
     </property> 
     <property name="title"> 
     <string>GroupBox</string> 
     </property> 
     </widget> 
     </item> 
     <item> 
     <widget class="QGroupBox" name="groupBox_3"> 
     <property name="minimumSize"> 
     <size> 
      <width>485</width> 
      <height>204</height> 
     </size> 
     </property> 
     <property name="maximumSize"> 
     <size> 
      <width>485</width> 
      <height>204</height> 
     </size> 
     </property> 
     <property name="title"> 
     <string>GroupBox</string> 
     </property> 
     </widget> 
     </item> 
     <item> 
     <widget class="QGroupBox" name="groupBox_4"> 
     <property name="minimumSize"> 
     <size> 
      <width>485</width> 
      <height>204</height> 
     </size> 
     </property> 
     <property name="maximumSize"> 
     <size> 
      <width>485</width> 
      <height>204</height> 
     </size> 
     </property> 
     <property name="title"> 
     <string>GroupBox</string> 
     </property> 
     </widget> 
     </item> 
     <item> 
     <spacer name="verticalSpacer"> 
     <property name="orientation"> 
     <enum>Qt::Vertical</enum> 
     </property> 
     <property name="sizeHint" stdset="0"> 
     <size> 
      <width>20</width> 
      <height>40</height> 
     </size> 
     </property> 
     </spacer> 
     </item> 
    </layout> 
    </item> 
    </layout> 
    </widget> 
    <widget class="QMenuBar" name="menuBar"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>1000</width> 
    <height>21</height> 
    </rect> 
    </property> 
    </widget> 
    <widget class="QToolBar" name="toolBar"> 
    <property name="windowTitle"> 
    <string>toolBar</string> 
    </property> 
    <attribute name="toolBarArea"> 
    <enum>TopToolBarArea</enum> 
    </attribute> 
    <attribute name="toolBarBreak"> 
    <bool>false</bool> 
    </attribute> 
    </widget> 
    <widget class="QStatusBar" name="statusBar"/> 
</widget> 
<layoutdefault spacing="6" margin="11"/> 
<customwidgets> 
    <customwidget> 
    <class>GroupBoxHFW</class> 
    <extends>QGroupBox</extends> 
    <header>GroupBoxHFW.h</header> 
    <container>1</container> 
    </customwidget> 
</customwidgets> 
<resources/> 
<connections/> 
</ui> 

GroupBoxHFW.h

#ifndef GROUPBOXHFW_H 
#define GROUPBOXHFW_H 

#include <QGroupBox> 

class GroupBoxHFW : public QGroupBox 
{ 
public: 
    GroupBoxHFW(QWidget * parent = 0); 
    GroupBoxHFW(const QString & title, QWidget * parent = 0); 

    int heightForWidth(int w) const; 
    bool hasHeightForWidth() const; 
}; 

#endif // GROUPBOXHFW_H 

GroupBoxHFW.cpp

#include "GroupBoxHFW.h" 

#include <QDebug> 

GroupBoxHFW::GroupBoxHFW(QWidget * parent) : QGroupBox(parent) 
{ 
    QSizePolicy policy(this->sizePolicy()); 
    policy.setHeightForWidth(true); 

    this->setSizePolicy(policy); 
} 

GroupBoxHFW::GroupBoxHFW(const QString & title, QWidget * parent) : QGroupBox(title, parent) 
{ 
    QSizePolicy policy(this->sizePolicy()); 
    policy.setHeightForWidth(true); 

    this->setSizePolicy(policy); 
} 


int GroupBoxHFW::heightForWidth(int w) const 
{ 
    qDebug() << "GroupBoxHFW::heightForWidth called"; 
    return 9.f/16.f * w; 
} 

bool GroupBoxHFW::hasHeightForWidth() const 
{ 
    qDebug() << "GroupBoxHFW::hasHeightForWidth called"; 
    return true; 
} 

正如你所看到的,我重新實現了虛擬函數int heightForWidth(int w) constbool hasHeightForWidth() const,希望我的QGroupBox自動調整到16/9的寬高比。不幸的是,它不起作用。在程序啓動時僅調用一次GroupBoxHFW::heightForWidth(),它甚至不會調整窗口小部件的大小。

這裏是程序的輸出:

GroupBoxHFW::hasHeightForWidth called 
horizontalLayout->hasHeightForWidth: true 
GroupBoxHFW::hasHeightForWidth called 
GroupBoxHFW::heightForWidth called 
GroupBoxHFW::hasHeightForWidth called 
GroupBoxHFW::hasHeightForWidth called 
GroupBoxHFW::hasHeightForWidth called 
GroupBoxHFW::hasHeightForWidth called 

什麼甚至離奇的是,雖然QGroupBox被調整上面這些都不是(hasHeightForWidth()heightForWidth()功能得到當我調整窗口調用,

怎麼了?如果這組框是垂直佈局裏面

+0

在[如何維護Qt中的窗口小部件寬高比?](http://stackoverflow.com/questions/452333/how-to-maintain-widgets-aspect-ratio-in-qt)有人提到,子類' QLayout「並覆蓋heightforwidth方法是更好的方法。 – Trilarion

+0

所以我只需要子類化QLayout並重寫'hasHeightForWidth()'和'heightForWidth()'就像我爲QGroupBox做的那樣? – GuiTeK

+0

我這麼認爲,但我從來沒有做過,所以我不能保證。 – Trilarion

回答

2

你的方法可以工作。

如名稱所示,hasHeightForWidth在高度取決於寬度(這是爲文字環繞設計的)而不是其他方式(您的情況)時很好定義。

你可以做什麼?試試這個(我實現了類似的東西爲QGraphicsWidget和它合作得非常好):

QSize GroupBoxHFW::sizeHint() const { 
    QSize s = size(); 
    lastHeight = s.height(); 
    s.setWidth((s.height()*16)/9); 
    s.setHeight(QGroupBox::sizeHint().height()); 
    return s; 
} 

void GroupBoxHFW::resizeEvent(QResizeEvent * event) { 
    QGroupBox::resizeEvent(event); 

    if (lastHeight!=height()) { 
     updateGeometry(); // it is possible that this call should be scheduled to next iteration of event loop 
    } 
} 

小題外話:
如果我會做,我會盡力落實子類此功能的QLayout和而不是作爲某些QWidget的子類。這樣它可以多次用於不同的小部件。

+0

它也不起作用。 注意:你忘了'sizeHint()'是const,你不能在這個函數內分配一個成員變量('lastHeight')。我刪除了'resizeEvent()'中的條件來解決這個問題。 – GuiTeK

+1

爲此字段添加關鍵字'mutable'。 'resizeEvent'中的條件是必須的,以防止無限循環。 –

+1

我也假設你已經使用了適當的尺寸策略。橫向尺寸政策應該是「固定的」。 –

相關問題