使用布局管理器管理不同大小的不同小部件

Posted

技术标签:

【中文标题】使用布局管理器管理不同大小的不同小部件【英文标题】:Management of different widgets of different sizes using layout managers 【发布时间】:2020-06-12 14:50:35 【问题描述】:

我想开发一个应用程序,它由不同大小的不同小部件组成,如所提供的图片所示。当我使用特定布局时,例如网格布局小部件在窗口上被组织为相等的部分。但我希望它们显示为不同的尺寸。

示例代码(.py)在这里。我想降低 QGroupBox 的高度

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1123, 855)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.frame = QtWidgets.QFrame(self.centralwidget)
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.frame)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.groupBox = QtWidgets.QGroupBox(self.frame)
        self.groupBox.setObjectName("groupBox")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.groupBox)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.label = QtWidgets.QLabel(self.groupBox)
        self.label.setObjectName("label")
        self.horizontalLayout.addWidget(self.label)
        self.label_2 = QtWidgets.QLabel(self.groupBox)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout.addWidget(self.label_2)
        self.label_3 = QtWidgets.QLabel(self.groupBox)
        self.label_3.setObjectName("label_3")
        self.horizontalLayout.addWidget(self.label_3)
        self.label_4 = QtWidgets.QLabel(self.groupBox)
        self.label_4.setObjectName("label_4")
        self.horizontalLayout.addWidget(self.label_4)
        self.gridLayout_2.addWidget(self.groupBox, 0, 0, 1, 1)
        self.splitter = QtWidgets.QSplitter(self.frame)
        self.splitter.setOrientation(QtCore.Qt.Horizontal)
        self.splitter.setObjectName("splitter")
        self.verticalLayoutWidget = QtWidgets.QWidget(self.splitter)
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.radioButton_2 = QtWidgets.QRadioButton(self.verticalLayoutWidget)
        self.radioButton_2.setObjectName("radioButton_2")
        self.verticalLayout.addWidget(self.radioButton_2)
        self.radioButton = QtWidgets.QRadioButton(self.verticalLayoutWidget)
        self.radioButton.setObjectName("radioButton")
        self.verticalLayout.addWidget(self.radioButton)
        self.verticalLayoutWidget_2 = QtWidgets.QWidget(self.splitter)
        self.verticalLayoutWidget_2.setObjectName("verticalLayoutWidget_2")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_2)
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.radioButton_3 = QtWidgets.QRadioButton(self.verticalLayoutWidget_2)
        self.radioButton_3.setObjectName("radioButton_3")
        self.verticalLayout_2.addWidget(self.radioButton_3)
        self.radioButton_4 = QtWidgets.QRadioButton(self.verticalLayoutWidget_2)
        self.radioButton_4.setObjectName("radioButton_4")
        self.verticalLayout_2.addWidget(self.radioButton_4)
        self.gridLayout_2.addWidget(self.splitter, 1, 0, 1, 1)
        self.gridLayout.addWidget(self.frame, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1123, 26))
        self.menubar.setObjectName("menubar")
        self.menuManage_Teams = QtWidgets.QMenu(self.menubar)
        self.menuManage_Teams.setObjectName("menuManage_Teams")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.actionNEW_Team = QtWidgets.QAction(MainWindow)
        self.actionNEW_Team.setObjectName("actionNEW_Team")
        self.actionOPEN_Team = QtWidgets.QAction(MainWindow)
        self.actionOPEN_Team.setObjectName("actionOPEN_Team")
        self.actionSAVE_Team = QtWidgets.QAction(MainWindow)
        self.actionSAVE_Team.setObjectName("actionSAVE_Team")
        self.actionEVALUATE_Team = QtWidgets.QAction(MainWindow)
        self.actionEVALUATE_Team.setObjectName("actionEVALUATE_Team")
        self.menuManage_Teams.addAction(self.actionNEW_Team)
        self.menuManage_Teams.addSeparator()
        self.menuManage_Teams.addAction(self.actionOPEN_Team)
        self.menuManage_Teams.addSeparator()
        self.menuManage_Teams.addAction(self.actionSAVE_Team)
        self.menuManage_Teams.addSeparator()
        self.menuManage_Teams.addAction(self.actionEVALUATE_Team)
        self.menubar.addAction(self.menuManage_Teams.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.groupBox.setTitle(_translate("MainWindow", "GroupBox"))
        self.label.setText(_translate("MainWindow", "TextLabel"))
        self.label_2.setText(_translate("MainWindow", "TextLabel"))
        self.label_3.setText(_translate("MainWindow", "TextLabel"))
        self.label_4.setText(_translate("MainWindow", "TextLabel"))
        self.radioButton_2.setText(_translate("MainWindow", "RadioButton"))
        self.radioButton.setText(_translate("MainWindow", "RadioButton"))
        self.radioButton_3.setText(_translate("MainWindow", "RadioButton"))
        self.radioButton_4.setText(_translate("MainWindow", "RadioButton"))
        self.menuManage_Teams.setTitle(_translate("MainWindow", "Manage Teams"))
        self.actionNEW_Team.setText(_translate("MainWindow", "NEW Team"))
        self.actionOPEN_Team.setText(_translate("MainWindow", "OPEN Team"))
        self.actionSAVE_Team.setText(_translate("MainWindow", "SAVE Team"))
        self.actionEVALUATE_Team.setText(_translate("MainWindow", "EVALUATE Team"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

这是 .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>1123</width>
    <height>855</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout">
    <item row="0" column="0">
     <widget class="QFrame" name="frame">
      <property name="frameShape">
       <enum>QFrame::StyledPanel</enum>
      </property>
      <property name="frameShadow">
       <enum>QFrame::Raised</enum>
      </property>
      <layout class="QGridLayout" name="gridLayout_2">
       <item row="0" column="0">
        <widget class="QGroupBox" name="groupBox">
         <property name="title">
          <string>GroupBox</string>
         </property>
         <layout class="QHBoxLayout" name="horizontalLayout">
          <item>
           <widget class="QLabel" name="label">
            <property name="text">
             <string>TextLabel</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QLabel" name="label_2">
            <property name="text">
             <string>TextLabel</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QLabel" name="label_3">
            <property name="text">
             <string>TextLabel</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QLabel" name="label_4">
            <property name="text">
             <string>TextLabel</string>
            </property>
           </widget>
          </item>
         </layout>
        </widget>
       </item>
       <item row="1" column="0">
        <widget class="QSplitter" name="splitter">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
         <widget class="QWidget" name="verticalLayoutWidget">
          <layout class="QVBoxLayout" name="verticalLayout">
           <item>
            <widget class="QRadioButton" name="radioButton_2">
             <property name="text">
              <string>RadioButton</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QRadioButton" name="radioButton">
             <property name="text">
              <string>RadioButton</string>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
         <widget class="QWidget" name="verticalLayoutWidget_2">
          <layout class="QVBoxLayout" name="verticalLayout_2">
           <item>
            <widget class="QRadioButton" name="radioButton_3">
             <property name="text">
              <string>RadioButton</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QRadioButton" name="radioButton_4">
             <property name="text">
              <string>RadioButton</string>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>1123</width>
     <height>26</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuManage_Teams">
    <property name="title">
     <string>Manage Teams</string>
    </property>
    <addaction name="actionNEW_Team"/>
    <addaction name="separator"/>
    <addaction name="actionOPEN_Team"/>
    <addaction name="separator"/>
    <addaction name="actionSAVE_Team"/>
    <addaction name="separator"/>
    <addaction name="actionEVALUATE_Team"/>
   </widget>
   <addaction name="menuManage_Teams"/>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
  <action name="actionNEW_Team">
   <property name="text">
    <string>NEW Team</string>
   </property>
  </action>
  <action name="actionOPEN_Team">
   <property name="text">
    <string>OPEN Team</string>
   </property>
  </action>
  <action name="actionSAVE_Team">
   <property name="text">
    <string>SAVE Team</string>
   </property>
  </action>
  <action name="actionEVALUATE_Team">
   <property name="text">
    <string>EVALUATE Team</string>
   </property>
  </action>
 </widget>
 <resources/>
 <connections/>
</ui>

【问题讨论】:

请提供minimal reproducible example 你能告诉我一些使用qt设计器设计窗口的基本步骤吗? 您说您已经使用过 QGridLayout 并且遇到了拉伸问题,所以如果您可以提供该代码,那么也许我们会帮助您建立这些拉伸。 我添加了一个示例代码,我想降低 QGroupBox 的高度 你能分享一下.ui吗?从而能够轻松修改它 【参考方案1】:

解决方案是设置拉伸因子,在您的情况下,您应该单击 topLevel 下方的 QFrame 并在 0,1 处查找 QGridLayout 的 layoutRowStrecth 部分:

<?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>1123</width>
    <height>855</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout">
    <item row="0" column="0">
     <widget class="QFrame" name="frame">
      <property name="frameShape">
       <enum>QFrame::StyledPanel</enum>
      </property>
      <property name="frameShadow">
       <enum>QFrame::Raised</enum>
      </property>
      <layout class="QGridLayout" name="gridLayout_2" rowstretch="0,1" rowminimum>
       <item row="0" column="0">
        <widget class="QGroupBox" name="groupBox">
         <property name="title">
          <string>GroupBox</string>
         </property>
         <layout class="QHBoxLayout" name="horizontalLayout">
          <item>
           <widget class="QLabel" name="label">
            <property name="text">
             <string>TextLabel</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QLabel" name="label_2">
            <property name="text">
             <string>TextLabel</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QLabel" name="label_3">
            <property name="text">
             <string>TextLabel</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QLabel" name="label_4">
            <property name="text">
             <string>TextLabel</string>
            </property>
           </widget>
          </item>
         </layout>
        </widget>
       </item>
       <item row="1" column="0">
        <widget class="QSplitter" name="splitter">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
         <widget class="QWidget" name="verticalLayoutWidget">
          <layout class="QVBoxLayout" name="verticalLayout">
           <item>
            <widget class="QRadioButton" name="radioButton_2">
             <property name="text">
              <string>RadioButton</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QRadioButton" name="radioButton">
             <property name="text">
              <string>RadioButton</string>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
         <widget class="QWidget" name="verticalLayoutWidget_2">
          <layout class="QVBoxLayout" name="verticalLayout_2">
           <item>
            <widget class="QRadioButton" name="radioButton_3">
             <property name="text">
              <string>RadioButton</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QRadioButton" name="radioButton_4">
             <property name="text">
              <string>RadioButton</string>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>1123</width>
     <height>26</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuManage_Teams">
    <property name="title">
     <string>Manage Teams</string>
    </property>
    <addaction name="actionNEW_Team"/>
    <addaction name="separator"/>
    <addaction name="actionOPEN_Team"/>
    <addaction name="separator"/>
    <addaction name="actionSAVE_Team"/>
    <addaction name="separator"/>
    <addaction name="actionEVALUATE_Team"/>
   </widget>
   <addaction name="menuManage_Teams"/>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
  <action name="actionNEW_Team">
   <property name="text">
    <string>NEW Team</string>
   </property>
  </action>
  <action name="actionOPEN_Team">
   <property name="text">
    <string>OPEN Team</string>
   </property>
  </action>
  <action name="actionSAVE_Team">
   <property name="text">
    <string>SAVE Team</string>
   </property>
  </action>
  <action name="actionEVALUATE_Team">
   <property name="text">
    <string>EVALUATE Team</string>
   </property>
  </action>
 </widget>
 <resources/>
 <connections/>
</ui>

另一方面,您可以通过多种方式实现您想要的,例如使用应用相同上下文的 QVBoxLayout。

<?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>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,1">
    <item>
     <widget class="QGroupBox" name="groupBox">
      <property name="title">
       <string>Your Selections:</string>
      </property>
      <layout class="QHBoxLayout" name="horizontalLayout">
       <item>
        <widget class="QLabel" name="label">
         <property name="text">
          <string>Batsmen(BAT)</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QLabel" name="label_2">
         <property name="text">
          <string>Bowlers(BOW)</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QLabel" name="label_3">
         <property name="text">
          <string>Allrounders(AR)</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QLabel" name="label_4">
         <property name="text">
          <string>Wicket-keeper(WK)</string>
         </property>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
    <item>
     <widget class="QSplitter" name="splitter">
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
      <widget class="QGroupBox" name="groupBox_2">
       <property name="title">
        <string>Points Available</string>
       </property>
       <layout class="QVBoxLayout" name="verticalLayout">
        <item>
         <layout class="QHBoxLayout" name="horizontalLayout_2">
          <item>
           <widget class="QRadioButton" name="radioButton">
            <property name="text">
             <string>BAT</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QRadioButton" name="radioButton_2">
            <property name="text">
             <string>BOW</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QRadioButton" name="radioButton_3">
            <property name="text">
             <string>AR</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QRadioButton" name="radioButton_4">
            <property name="text">
             <string>WK</string>
            </property>
           </widget>
          </item>
         </layout>
        </item>
        <item>
         <spacer name="verticalSpacer">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>394</height>
           </size>
          </property>
         </spacer>
        </item>
       </layout>
      </widget>
      <widget class="QGroupBox" name="groupBox_3">
       <property name="title">
        <string>Points Used</string>
       </property>
       <layout class="QVBoxLayout" name="verticalLayout_2">
        <item>
         <layout class="QHBoxLayout" name="horizontalLayout_3">
          <item>
           <widget class="QLabel" name="label_5">
            <property name="text">
             <string>Team Name</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QLabel" name="label_6">
            <property name="text">
             <string>Displayed  here</string>
            </property>
           </widget>
          </item>
         </layout>
        </item>
        <item>
         <spacer name="verticalSpacer_2">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>400</height>
           </size>
          </property>
         </spacer>
        </item>
       </layout>
      </widget>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>26</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

【讨论】:

以上是关于使用布局管理器管理不同大小的不同小部件的主要内容,如果未能解决你的问题,请参考以下文章

每个容器都有一个布局管理器

QT 布局管理器在移动窗口之前隐藏小部件时不会恢复空间

wxpython 布局管理

第十一周课程总结

QT 学习笔记概述

Java 使用布局管理器后怎样设置控件的大小。