Home > Mobile >  PySide2: Promoted placeholder widget layout position & resizing
PySide2: Promoted placeholder widget layout position & resizing

Time:03-03

I'm facing an issue by showing correctly a promoted widget. I have two simple designs in .ui files made with QtDesginer. One is a simple calendar and the other is just a simple empty widget.

Empty Widget Design: Empty Widget

Calendar Design: Calendar

So the idea is to promote the Calendar from the empty widget that serves as placeholder, when i do that works ok, the widget promoted is shown correctly except for the position.

Promoted Widget Running and showing: Promoted widget

As you can see in the QtDesigner pictures both have a Vertical Layout, so is intended the widgets show and place uniformly along the form and when resizing it too. As you can see the calendar is placed into the top left corner and if I resize the window, it keep stuck in the corner making the layout ignore.

Resized window with promoted widget stuck in top left corner: Promoted resized

Is it assumed that if the widget that serves as placeholder is into a layout and if I run it alone resize uniformly, the promoted widget should place and resize uniformly too? isn't it?

May anybody help me to figure out how to make the promoted widget doesn't ignore the layout and show centered and resize uniformly?

Expected behaviour. Resized uniformly as when I run calendar just alone without promoting: Calendar widget

I also have used QFrame as placeholder but with the same result.

This is my code:

EmptyWidget as place holder: myform.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget  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  name="horizontalLayout">
   <item>
    <widget  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>

Calendar: Mypromoted.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget  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  name="verticalLayout">
   <item>
    <widget  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 Mint 20.3

CodePudding user response:

The main problem with your example is that it does not set a layout on either the HolderCalendar widget or the PromoteCalendar widget. The QUiLoader.load function returns a completely separate widget which will not resize along with the top-level window unless it's contained within the main layout hierarchy. The two classes should therefore be re-written as follows:

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

You may also want to make two other changes:

Firstly, to avoid the extra spacing around the calandar, reset all the layout margins to zero in Qt Designer. This can be done by selecting the top-level Form widget, and then scrolling down to the Layout section in the Property Editor.

Secondly, you will notice that the background colour of the calendar is affected by the stylesheet set on the placeholder widget. To avoid this, in Qt Designer, change the stylesheet of the placeholder to #Cal_Placeholder {background-color: rgb(186, 189, 182)}.

  • Related