PySide2:提升的占位符小部件布局位置和调整大小

PySide2: Promoted placeholder widget layout position & resizing

我在正确显示升级的小部件时遇到了问题。我在使用 QtDesginer 制作的 .ui 文件中有两个简单的设计。一个是简单的日历,另一个只是一个简单的空小部件。

空白小部件设计:

日历设计:

所以我的想法是从用作占位符的空小部件提升日历,当我这样做时工作正常,除了位置之外,提升的小部件显示正确。

已推广的小部件 运行 并显示:

正如您在 QtDesigner 图片中看到的那样,它们都具有垂直布局,因此小部件旨在沿窗体统一显示和放置,并且在调整窗体大小时也是如此。 如您所见,日历放在左上角,如果我调整 window 的大小,它会一直卡在角落里,导致布局被忽略。

调整大小 window,提升的小部件卡在左上角:

是否假定如果用作占位符的小部件进入布局并且如果我 运行 它单独统一调整大小,则提升的小部件也应该统一放置和调整大小?不是吗?

谁能帮我弄清楚如何使提升的小部件不忽略布局并居中显示并统一调整大小?

预期的行为。统一调整大小,就像我 运行 日历没有推广时一样:

我也使用 QFrame 作为占位符,但结果相同。

这是我的代码:

EmptyWidget 作为占位符:myform.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>650</width>
    <height>650</height>
   </rect>
  </property>
  <property name="minimumSize">
   <size>
    <width>650</width>
    <height>650</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>MyFORM</string>
  </property>
  <layout class="QHBoxLayout" name="horizontalLayout">
   <item>
    <widget class="PromoteCalendar" name="Cal_Placeholder" native="true">
     <property name="styleSheet">
      <string notr="true">background-color: rgb(186, 189, 182);</string>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
 <customwidgets>
  <customwidget>
   <class>PromoteCalendar</class>
   <extends>QWidget</extends>
   <header>mypromote</header>
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

日历:Mypromoted.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>500</width>
    <height>500</height>
   </rect>
  </property>
  <property name="minimumSize">
   <size>
    <width>500</width>
    <height>500</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>Calendar</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <widget class="QCalendarWidget" name="calendarWidget"/>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

holdmycalendar.py

from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import *
from calendar import PromoteCalendar


class HolderCalendar(QWidget):
    def __init__(self,file_name, parent):
        super().__init__(parent)

        self.loader=QUiLoader()
        self.loader.registerCustomWidget(PromoteCalendar)
        self.ui=self.loader.load(file_name)
        
        self.ui.show()


if __name__=='__main__':
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_ShareOpenGLContexts)
    app=QApplication(sys.argv)
    window = HolderCalendar('myform.ui', None)
    app.exec_()

calendar.py

from PySide2 import QtCore ,QtGui, QtWidgets
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import *

class PromoteCalendar(QWidget):
    def __init__(self,parent=None):
        super().__init__(parent)



        self.loader=QUiLoader()
        self.ui=self.loader.load('Mypromoted.ui',parent)

Python 3.8.10 PySide2 5.15.2 Linux 薄荷 20.3

您的示例的主要问题是它没有在 HolderCalendar 小部件或 PromoteCalendar 小部件上设置布局。 QUiLoader.load 函数 returns 一个 完全独立的小部件 不会随 top-level window 一起调整大小,除非它包含在主布局中等级制度。两个类因此应该是re-written如下:

class PromoteCalendar(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        self.ui = QUiLoader().load('Mypromoted.ui')
        layout.addWidget(self.ui)
class HolderCalendar(QWidget):
    def __init__(self, file_name, parent):
        super().__init__(parent)
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        loader = QUiLoader()
        loader.registerCustomWidget(PromoteCalendar)
        self.ui = loader.load(file_name)
        layout.addWidget(self.ui)
        self.show()

您可能还想进行另外两项更改:

首先,为了避免日历周围的额外间距,在 Qt Designer 中将所有布局边距重置为零。这可以通过选择 top-level 表单小部件,然后向下滚动到 属性 编辑器中的布局部分来完成。

其次,您会注意到日历的背景颜色受占位符小部件上设置的样式表的影响。为避免这种情况,在 Qt Designer 中,将占位符的样式表更改为 #Cal_Placeholder {background-color: rgb(186, 189, 182)}.