如何将项目动态添加到QHorizo ntal布局中而不影响窗口大小或布局中的其他项目?

问题描述 投票:0回答:1

我有一个水平布局,其中包含用于搜索/过滤TableView的各种工具栏。用户应该从前两个组合框中选择一列和一个运算符,在文本字段中输入搜索词组,然后单击“搜索”按钮以过滤表。有一个“重置”按钮,它清除所有添加的过滤器,然后是一个水平间隔符,用于将这组窗口小部件与右侧的“绘图”按钮分开。

看起来像这样

“”

所有小部件的大小策略都设置为“最小”,除了文本字段(扩展)和水平分隔符(忽略)。

我想在“重置”按钮的右侧添加一个QLabel,以总结刚刚添加的过滤器,如下所示。

“”

问题是,我的水平间隔物不会收缩以允许QLabel占用空间,因此整个窗口的大小都会调整。这是一个问题,因为我已经实现了“堆叠”过滤器,并希望向用户显示已添加到表中的每个过滤器。

理想地,随着添加了越来越多的滤镜,我希望QLabels缩小水平间隔物直到有效地消失,然后让它们均匀地收缩以适应“重置”按钮和“绘图”按钮之间的空间。我从不希望QLabels完全影响整个窗口的大小。

我已经尝试将水平间隔的尺寸策略设置为忽略,最小和最大,并且它没有任何影响,即当添加QLabel时,整个窗口都变得适合它们。我还尝试了水平放置从布局中删除间隔,插入QLabel,然后重新添加间隔以“刷新”水平布局(如this论坛中的建议)。

exampleUI.py(使用pyuic5自动生成):

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'example.ui'
#
# Created by: PyQt5 UI code generator 5.12.1
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1538, 843)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.centralwidget)
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.splitter_2 = QtWidgets.QSplitter(self.centralwidget)
        self.splitter_2.setOrientation(QtCore.Qt.Horizontal)
        self.splitter_2.setObjectName("splitter_2")
        self.treeWidget = QtWidgets.QTreeWidget(self.splitter_2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(5)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(self.treeWidget.sizePolicy().hasHeightForWidth())
        self.treeWidget.setSizePolicy(sizePolicy)
        self.treeWidget.setObjectName("treeWidget")
        item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
        item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
        item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
        item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
        item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
        self.splitter = QtWidgets.QSplitter(self.splitter_2)
        self.splitter.setOrientation(QtCore.Qt.Vertical)
        self.splitter.setObjectName("splitter")
        self.Widget = QtWidgets.QWidget(self.splitter)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(4)
        sizePolicy.setHeightForWidth(self.Widget.sizePolicy().hasHeightForWidth())
        self.Widget.setSizePolicy(sizePolicy)
        self.Widget.setObjectName("Widget")
        self.tabWidget = QtWidgets.QTabWidget(self.splitter)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(2)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth())
        self.tabWidget.setSizePolicy(sizePolicy)
        self.tabWidget.setObjectName("tabWidget")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.tab_2)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.columnComboBox_2 = QtWidgets.QComboBox(self.tab_2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.columnComboBox_2.sizePolicy().hasHeightForWidth())
        self.columnComboBox_2.setSizePolicy(sizePolicy)
        self.columnComboBox_2.setObjectName("columnComboBox_2")
        self.columnComboBox_2.addItem("")
        self.columnComboBox_2.addItem("")
        self.columnComboBox_2.addItem("")
        self.columnComboBox_2.addItem("")
        self.columnComboBox_2.addItem("")
        self.columnComboBox_2.addItem("")
        self.columnComboBox_2.addItem("")
        self.horizontalLayout_2.addWidget(self.columnComboBox_2)
        self.operatorComboBox_2 = QtWidgets.QComboBox(self.tab_2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.operatorComboBox_2.sizePolicy().hasHeightForWidth())
        self.operatorComboBox_2.setSizePolicy(sizePolicy)
        self.operatorComboBox_2.setObjectName("operatorComboBox_2")
        self.operatorComboBox_2.addItem("")
        self.operatorComboBox_2.addItem("")
        self.operatorComboBox_2.addItem("")
        self.operatorComboBox_2.addItem("")
        self.operatorComboBox_2.addItem("")
        self.operatorComboBox_2.addItem("")
        self.horizontalLayout_2.addWidget(self.operatorComboBox_2)
        self.FilterBar_2 = QtWidgets.QLineEdit(self.tab_2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(3)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.FilterBar_2.sizePolicy().hasHeightForWidth())
        self.FilterBar_2.setSizePolicy(sizePolicy)
        self.FilterBar_2.setObjectName("FilterBar_2")
        self.horizontalLayout_2.addWidget(self.FilterBar_2)
        self.SearchButton_2 = QtWidgets.QPushButton(self.tab_2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.SearchButton_2.sizePolicy().hasHeightForWidth())
        self.SearchButton_2.setSizePolicy(sizePolicy)
        self.SearchButton_2.setObjectName("SearchButton_2")
        self.horizontalLayout_2.addWidget(self.SearchButton_2)
        self.resetFilterButton_2 = QtWidgets.QPushButton(self.tab_2)
        self.resetFilterButton_2.setObjectName("resetFilterButton_2")
        self.horizontalLayout_2.addWidget(self.resetFilterButton_2)
        spacerItem = QtWidgets.QSpacerItem(800, 20, QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem)
        self.pushButton_2 = QtWidgets.QPushButton(self.tab_2)
        self.pushButton_2.setObjectName("pushButton_2")
        self.horizontalLayout_2.addWidget(self.pushButton_2)
        self.verticalLayout_2.addLayout(self.horizontalLayout_2)
        self.tableView_2 = QtWidgets.QTableView(self.tab_2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(2)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.tableView_2.sizePolicy().hasHeightForWidth())
        self.tableView_2.setSizePolicy(sizePolicy)
        self.tableView_2.setObjectName("tableView_2")
        self.verticalLayout_2.addWidget(self.tableView_2)
        self.horizontalLayout_3.addLayout(self.verticalLayout_2)
        self.tabWidget.addTab(self.tab_2, "")
        self.horizontalLayout_5.addWidget(self.splitter_2)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1538, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.treeWidget.headerItem().setText(0, _translate("MainWindow", "Account"))
        self.treeWidget.headerItem().setText(1, _translate("MainWindow", "Balance"))
        __sortingEnabled = self.treeWidget.isSortingEnabled()
        self.treeWidget.setSortingEnabled(False)
        self.treeWidget.topLevelItem(0).setText(0, _translate("MainWindow", "Cash"))
        self.treeWidget.topLevelItem(1).setText(0, _translate("MainWindow", "Credit"))
        self.treeWidget.topLevelItem(2).setText(0, _translate("MainWindow", "Investments"))
        self.treeWidget.topLevelItem(3).setText(0, _translate("MainWindow", "Loans"))
        self.treeWidget.topLevelItem(4).setText(0, _translate("MainWindow", "Property"))
        self.treeWidget.setSortingEnabled(__sortingEnabled)
        self.columnComboBox_2.setItemText(0, _translate("MainWindow", "Column:"))
        self.columnComboBox_2.setItemText(1, _translate("MainWindow", "Date"))
        self.columnComboBox_2.setItemText(2, _translate("MainWindow", "Merchant"))
        self.columnComboBox_2.setItemText(3, _translate("MainWindow", "Category"))
        self.columnComboBox_2.setItemText(4, _translate("MainWindow", "Amount"))
        self.columnComboBox_2.setItemText(5, _translate("MainWindow", "Account"))
        self.columnComboBox_2.setItemText(6, _translate("MainWindow", "F.I."))
        self.operatorComboBox_2.setItemText(0, _translate("MainWindow", "="))
        self.operatorComboBox_2.setItemText(1, _translate("MainWindow", "<"))
        self.operatorComboBox_2.setItemText(2, _translate("MainWindow", ">"))
        self.operatorComboBox_2.setItemText(3, _translate("MainWindow", "<="))
        self.operatorComboBox_2.setItemText(4, _translate("MainWindow", ">="))
        self.operatorComboBox_2.setItemText(5, _translate("MainWindow", "NOT"))
        self.FilterBar_2.setPlaceholderText(_translate("MainWindow", "Filter transactions..."))
        self.SearchButton_2.setText(_translate("MainWindow", "Search"))
        self.resetFilterButton_2.setText(_translate("MainWindow", "Reset"))
        self.pushButton_2.setText(_translate("MainWindow", "Plot"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Transactions"))




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_())

exampleApp.py(应用程序类:)

from exampleUI import Ui_MainWindow
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QSizePolicy
import sys

class exampleApp:

    def __init__(self):
        # Initialize QtWidgets
        self.MainWindow = QtWidgets.QMainWindow()

        # Initialize UI objects
        self.MainWindowUi = Ui_MainWindow()

        # Plug QtWidget object into setupUi method of UI object
        self.MainWindowUi.setupUi(self.MainWindow)

        self.MainWindow.show()

        self.MainWindowUi.SearchButton_2.clicked.connect(lambda: self.add_filter(
            self.MainWindowUi.columnComboBox_2.currentText(), self.MainWindowUi.operatorComboBox_2.currentText(),
            self.MainWindowUi.FilterBar_2.text()))

    def add_filter(self, column, operator, phrase):
        filter_string = "{} {} {}".format(column, operator, phrase)

        label = QtWidgets.QLabel(filter_string)
        label.setToolTip(filter_string)
        label.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
        self.MainWindowUi.horizontalLayout_2.insertWidget(5, label, 0)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    ui = exampleApp()
    sys.exit(app.exec())

example.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>1538</width>
    <height>843</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QHBoxLayout" name="horizontalLayout_5">
    <item>
     <widget class="QSplitter" name="splitter_2">
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
      <widget class="QTreeWidget" name="treeWidget">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
         <horstretch>5</horstretch>
         <verstretch>1</verstretch>
        </sizepolicy>
       </property>
       <column>
        <property name="text">
         <string>Account</string>
        </property>
       </column>
       <column>
        <property name="text">
         <string>Balance</string>
        </property>
       </column>
       <item>
        <property name="text">
         <string>Cash</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>Credit</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>Investments</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>Loans</string>
        </property>
       </item>
       <item>
        <property name="text">
         <string>Property</string>
        </property>
       </item>
      </widget>
      <widget class="QSplitter" name="splitter">
       <property name="orientation">
        <enum>Qt::Vertical</enum>
       </property>
       <widget class="QWidget" name="Widget" native="true">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
          <horstretch>1</horstretch>
          <verstretch>4</verstretch>
         </sizepolicy>
        </property>
       </widget>
       <widget class="QTabWidget" name="tabWidget">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
          <horstretch>2</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="currentIndex">
         <number>0</number>
        </property>
        <widget class="QWidget" name="tab_2">
         <attribute name="title">
          <string>Transactions</string>
         </attribute>
         <layout class="QHBoxLayout" name="horizontalLayout_3">
          <item>
           <layout class="QVBoxLayout" name="verticalLayout_2">
            <item>
             <layout class="QHBoxLayout" name="horizontalLayout_2">
              <item>
               <widget class="QComboBox" name="columnComboBox_2">
                <property name="sizePolicy">
                 <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
                  <horstretch>1</horstretch>
                  <verstretch>0</verstretch>
                 </sizepolicy>
                </property>
                <item>
                 <property name="text">
                  <string>Column:</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>Date</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>Merchant</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>Category</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>Amount</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>Account</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>F.I.</string>
                 </property>
                </item>
               </widget>
              </item>
              <item>
               <widget class="QComboBox" name="operatorComboBox_2">
                <property name="sizePolicy">
                 <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
                  <horstretch>0</horstretch>
                  <verstretch>0</verstretch>
                 </sizepolicy>
                </property>
                <item>
                 <property name="text">
                  <string>=</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>&lt;</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>&gt;</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>&lt;=</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>&gt;=</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>NOT</string>
                 </property>
                </item>
               </widget>
              </item>
              <item>
               <widget class="QLineEdit" name="FilterBar_2">
                <property name="sizePolicy">
                 <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
                  <horstretch>3</horstretch>
                  <verstretch>0</verstretch>
                 </sizepolicy>
                </property>
                <property name="placeholderText">
                 <string>Filter transactions...</string>
                </property>
               </widget>
              </item>
              <item>
               <widget class="QPushButton" name="SearchButton_2">
                <property name="sizePolicy">
                 <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
                  <horstretch>0</horstretch>
                  <verstretch>0</verstretch>
                 </sizepolicy>
                </property>
                <property name="text">
                 <string>Search</string>
                </property>
               </widget>
              </item>
              <item>
               <widget class="QPushButton" name="resetFilterButton_2">
                <property name="text">
                 <string>Reset</string>
                </property>
               </widget>
              </item>
              <item>
               <spacer name="horizontalSpacer_2">
                <property name="orientation">
                 <enum>Qt::Horizontal</enum>
                </property>
                <property name="sizeType">
                 <enum>QSizePolicy::Ignored</enum>
                </property>
                <property name="sizeHint" stdset="0">
                 <size>
                  <width>800</width>
                  <height>20</height>
                 </size>
                </property>
               </spacer>
              </item>
              <item>
               <widget class="QPushButton" name="pushButton_2">
                <property name="text">
                 <string>Plot</string>
                </property>
               </widget>
              </item>
             </layout>
            </item>
            <item>
             <widget class="QTableView" name="tableView_2">
              <property name="sizePolicy">
               <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
                <horstretch>2</horstretch>
                <verstretch>0</verstretch>
               </sizepolicy>
              </property>
             </widget>
            </item>
           </layout>
          </item>
         </layout>
        </widget>
       </widget>
      </widget>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>1538</width>
     <height>26</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

为冗长的UI文件表示歉意,但是我认为捕获所有嵌套的布局交互以确保了解我的情况很重要。将exampleApp.py最小化以仅关注此问题。

[运行exampleApp.py,然后在文本字段中输入内容,然后从组合框中选择几个选项,然后多次按“搜索”按钮,会将几个标签插入水平布局并演示我的问题。

任何人都对我如何实现这一目标有任何想法?

python pyqt pyqt5
1个回答
0
投票

您(正如我们许多人一样,可能对大小策略的Minimum概念感到困惑。从技术上讲,该文档不是错误(但令人困惑),您“仅”需要一些注意和理解才能获得它。

Minimum”并不意味着该小部件将其大小提示用作“最小”大小,而是该大小提示“是最小的”(“ hint”是关键字:它是一个“建议”)。您实际上要查找的是Maximum:«小部件可以缩小任何尺寸” 但是«不能大于sizeHint()提供的大小,它会设置ShrinkFlag。据此,您可能也将以GrowFlag结尾(这确保了必要时小部件可以“增长”);这将带您使用Preferred sizePolicy,这是大多数QWidget的默认设置。仔细阅读QSizePolicy documentation,并亲自进行一些测试以更好地理解它。这需要一些时间和很多关注,但这是值得的。

所以,长话短说:不要为any小部件设置Minimum sizePolicy(除非确实需要)。请保留默认的Preferred策略,如果没有将其设置为默认大小策略,则对需要“消耗”所有可用空间的任何其他小部件使用Expanding。在您的特定情况下(至少根据您的问题),重置默认策略tabWidget可能就足够了,两个方向的默认策略均为Expanded(但我建议您“撤消” widget属性而不是手动设置)。

© www.soinside.com 2019 - 2024. All rights reserved.