Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Mixins - Inherits from two QLineEdits using UiLoader

Mixins - Inherits from two QLineEdits using UiLoader

Scheduled Pinned Locked Moved Solved Qt for Python
4 Posts 2 Posters 573 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    Flanagan
    wrote on last edited by Flanagan
    #1

    I have two custom QLineEdit:

    • ValidatedQLineEdit
    • DelayedQLineEdit

    If I want to have a QLineEdit with the functionality of both, how do I do it?

    I am doing this:

    class DelayedValidatedLineEdit(DelayedLineEdit, ValidatedLineEdit):
        pass
    

    But when I run it Qt creates an empty QLineEdit for me and then:
    da045f4a-2e85-4c4d-90e3-f7edf9fa58d3-image.png
    This happens because my two custom QLineEdit inherits from QLineEdit. If one of them did not inherit from anyone, it does work.

    If I create the DelayedValidatedLineEdit manually it works but I'm loading the ui file with the promoted QLineEdit and then this happens.

    from PySide2 import QtCore, QtWidgets
    
    from utils import Color
    
    
    class DelayedLineEdit(QtWidgets.QLineEdit):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
            self.delay = 250
            self.timer = QtCore.QTimer()
            self.timer.setSingleShot(True)
    
            self.textEdited.connect(self._restart_timer)
    
        def _restart_timer(self):
            self.timer.start(self.delay)
    
    
    class ValidatedLineEdit(QtWidgets.QLineEdit):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.color = Color.DEFAULT
    
        def color_default(self):
            if self.color != Color.DEFAULT:
                self.color = Color.DEFAULT
                self.setStyleSheet(None)
    
        def color_red(self):
            if self.color != Color.RED:
                self.color = Color.RED
                self.setStyleSheet('background-color: rgb(255, 200, 200)')
    
        def validate(self, extra_condition=True, validate_empty=True):
            if (not validate_empty or self.text()) and extra_condition:
                self.color_default()
            else:
                self.color_red()
    
    
    class DelayedValidatedLineEdit(DelayedLineEdit, ValidatedLineEdit):
        pass
    
    
    1 Reply Last reply
    0
    • F Flanagan

      @Denni-0

      Thank you very much for your work! I like your code, it shows that you have experience.

      That resource you found on google was one that I looked to try to fix this.

      I understand that super() is a problem because of the differences between Python and C++, I will try not to use it.

      I have had to make some modifications to your code to make it work with my UiLoader class. Unfortunately, in the end, it returns the same error as it had before.

      The modifications I have made to your code are the following:
      724bae5e-ea0f-470d-ba9e-e09b5a78492a-image.png
      And I've also had to add *args and **kwargs so UiLoader won't throw me an error.

      from PySide2.QtCore import *
      from PySide2.QtWidgets import *
      
      from utils import Color
      
      
      class Delayer(QTimer):
          def __init__(self, *args, **kwargs):
              QTimer.__init__(self, *args, **kwargs)
      
              self.delay = 250
              self.setSingleShot(True)
      
          def Restart(self):
              self.timer.start(self.delay)
      
      
      class DelayedLineEdit(QLineEdit):
          def __init__(self, *args, **kwargs):
              QLineEdit.__init__(self, *args, **kwargs)
      
              self.Delyr = Delayer()
              self.textEdited.connect(self.Delyr.Restart)
      
      
      class Validator(QObject):
          def __init__(self, LinEditr, *args, **kwargs):
              QObject.__init__(self, *args, **kwargs)
              self.LneEdt = LinEditr
              self.color = Color.DEFAULT
      
          def SetColorDefault(self):
              if self.color != Color.DEFAULT:
                  self.color = Color.DEFAULT
                  self.LneEdt.setStyleSheet(None)
      
          def SetColorRed(self):
              if self.color != Color.RED:
                  self.color = Color.RED
                  self.LneEdt.setStyleSheet('background-color: rgb(255, 200, 200)')
      
          def Valid(self, validate_empty=True, extra_condition=True):
              if (not validate_empty or self.LneEdt.text()) and extra_condition:
                  self.SetColorDefault()
              else:
                  self.SetColorRed()
      
      
      class ValidatedLineEdit(QLineEdit):
          def __init__(self, *args, **kwargs):
              QLineEdit.__init__(self, *args, **kwargs)
      
              self.Vldatr = Validator(self)
          # Nothing within your code snippet did more than this
          # which does nothing but I assume your finished piece
          # makes that connection
      
      
      class DelayedValidatedLineEdit(QLineEdit):
          def __init__(self, *args, **kwargs):
              QLineEdit.__init__(self, *args, **kwargs)
              # Here is the semi-universal Validator
              self.Vldatr = Validator(self)
      
              # Here is the semi-universal Delayer
              self.Delyr = Delayer()
              self.textEdited.connect(self.Delyr.Restart)
      

      I got my UiLoader class from these sources:

      • https://robonobodojo.wordpress.com/2017/10/03/loading-a-pyside-ui-via-a-class/
      • https://robonobodojo.wordpress.com/2018/10/29/pyside2-widget-class-from-a-qt-designer-ui/
      • https://gist.github.com/fredrikaverpil/0a89b174c9d29bc585f11d250adf2a7c

      My UiLoader class:

      from PySide2.QtUiTools import QUiLoader
      
      
      def load_ui(ui_file, base_instance=None, custom_classes=()):
          loader = UiLoader(base_instance)
          for custom_class in custom_classes:
              loader.registerCustomWidget(custom_class)
          loader.load(ui_file)
      
      
      class UiLoader(QUiLoader):
          def __init__(self, base_instance):
              super().__init__()
              self.base_instance = base_instance
      
          def createWidget(self, class_name, parent=None, name=''):
              if parent is None and self.base_instance:
                  return self.base_instance
              else:
                  return super().createWidget(class_name, parent, name)
      
      
      F Offline
      F Offline
      Flanagan
      wrote on last edited by
      #4

      And I fixed it, I have copied the code as is from the third link I put in one message above. Now it works.

      https://gist.github.com/fredrikaverpil/0a89b174c9d29bc585f11d250adf2a7c

      Now I can go in peace but against your recommendations xD

      1 Reply Last reply
      0
      • F Offline
        F Offline
        Flanagan
        wrote on last edited by
        #2

        @Denni-0

        Thank you very much for your work! I like your code, it shows that you have experience.

        That resource you found on google was one that I looked to try to fix this.

        I understand that super() is a problem because of the differences between Python and C++, I will try not to use it.

        I have had to make some modifications to your code to make it work with my UiLoader class. Unfortunately, in the end, it returns the same error as it had before.

        The modifications I have made to your code are the following:
        724bae5e-ea0f-470d-ba9e-e09b5a78492a-image.png
        And I've also had to add *args and **kwargs so UiLoader won't throw me an error.

        from PySide2.QtCore import *
        from PySide2.QtWidgets import *
        
        from utils import Color
        
        
        class Delayer(QTimer):
            def __init__(self, *args, **kwargs):
                QTimer.__init__(self, *args, **kwargs)
        
                self.delay = 250
                self.setSingleShot(True)
        
            def Restart(self):
                self.timer.start(self.delay)
        
        
        class DelayedLineEdit(QLineEdit):
            def __init__(self, *args, **kwargs):
                QLineEdit.__init__(self, *args, **kwargs)
        
                self.Delyr = Delayer()
                self.textEdited.connect(self.Delyr.Restart)
        
        
        class Validator(QObject):
            def __init__(self, LinEditr, *args, **kwargs):
                QObject.__init__(self, *args, **kwargs)
                self.LneEdt = LinEditr
                self.color = Color.DEFAULT
        
            def SetColorDefault(self):
                if self.color != Color.DEFAULT:
                    self.color = Color.DEFAULT
                    self.LneEdt.setStyleSheet(None)
        
            def SetColorRed(self):
                if self.color != Color.RED:
                    self.color = Color.RED
                    self.LneEdt.setStyleSheet('background-color: rgb(255, 200, 200)')
        
            def Valid(self, validate_empty=True, extra_condition=True):
                if (not validate_empty or self.LneEdt.text()) and extra_condition:
                    self.SetColorDefault()
                else:
                    self.SetColorRed()
        
        
        class ValidatedLineEdit(QLineEdit):
            def __init__(self, *args, **kwargs):
                QLineEdit.__init__(self, *args, **kwargs)
        
                self.Vldatr = Validator(self)
            # Nothing within your code snippet did more than this
            # which does nothing but I assume your finished piece
            # makes that connection
        
        
        class DelayedValidatedLineEdit(QLineEdit):
            def __init__(self, *args, **kwargs):
                QLineEdit.__init__(self, *args, **kwargs)
                # Here is the semi-universal Validator
                self.Vldatr = Validator(self)
        
                # Here is the semi-universal Delayer
                self.Delyr = Delayer()
                self.textEdited.connect(self.Delyr.Restart)
        

        I got my UiLoader class from these sources:

        • https://robonobodojo.wordpress.com/2017/10/03/loading-a-pyside-ui-via-a-class/
        • https://robonobodojo.wordpress.com/2018/10/29/pyside2-widget-class-from-a-qt-designer-ui/
        • https://gist.github.com/fredrikaverpil/0a89b174c9d29bc585f11d250adf2a7c

        My UiLoader class:

        from PySide2.QtUiTools import QUiLoader
        
        
        def load_ui(ui_file, base_instance=None, custom_classes=()):
            loader = UiLoader(base_instance)
            for custom_class in custom_classes:
                loader.registerCustomWidget(custom_class)
            loader.load(ui_file)
        
        
        class UiLoader(QUiLoader):
            def __init__(self, base_instance):
                super().__init__()
                self.base_instance = base_instance
        
            def createWidget(self, class_name, parent=None, name=''):
                if parent is None and self.base_instance:
                    return self.base_instance
                else:
                    return super().createWidget(class_name, parent, name)
        
        
        F 1 Reply Last reply
        0
        • F Offline
          F Offline
          Flanagan
          wrote on last edited by
          #3

          Yeah it works but the UiLoader is so useful... I can edit the gui, save and run. Otherwise you would have to generate the .py code, format the code ... (before doing it like this)

          I will search on the internet again to see if I find how to fix the UiLoader.

          1 Reply Last reply
          0
          • F Flanagan

            @Denni-0

            Thank you very much for your work! I like your code, it shows that you have experience.

            That resource you found on google was one that I looked to try to fix this.

            I understand that super() is a problem because of the differences between Python and C++, I will try not to use it.

            I have had to make some modifications to your code to make it work with my UiLoader class. Unfortunately, in the end, it returns the same error as it had before.

            The modifications I have made to your code are the following:
            724bae5e-ea0f-470d-ba9e-e09b5a78492a-image.png
            And I've also had to add *args and **kwargs so UiLoader won't throw me an error.

            from PySide2.QtCore import *
            from PySide2.QtWidgets import *
            
            from utils import Color
            
            
            class Delayer(QTimer):
                def __init__(self, *args, **kwargs):
                    QTimer.__init__(self, *args, **kwargs)
            
                    self.delay = 250
                    self.setSingleShot(True)
            
                def Restart(self):
                    self.timer.start(self.delay)
            
            
            class DelayedLineEdit(QLineEdit):
                def __init__(self, *args, **kwargs):
                    QLineEdit.__init__(self, *args, **kwargs)
            
                    self.Delyr = Delayer()
                    self.textEdited.connect(self.Delyr.Restart)
            
            
            class Validator(QObject):
                def __init__(self, LinEditr, *args, **kwargs):
                    QObject.__init__(self, *args, **kwargs)
                    self.LneEdt = LinEditr
                    self.color = Color.DEFAULT
            
                def SetColorDefault(self):
                    if self.color != Color.DEFAULT:
                        self.color = Color.DEFAULT
                        self.LneEdt.setStyleSheet(None)
            
                def SetColorRed(self):
                    if self.color != Color.RED:
                        self.color = Color.RED
                        self.LneEdt.setStyleSheet('background-color: rgb(255, 200, 200)')
            
                def Valid(self, validate_empty=True, extra_condition=True):
                    if (not validate_empty or self.LneEdt.text()) and extra_condition:
                        self.SetColorDefault()
                    else:
                        self.SetColorRed()
            
            
            class ValidatedLineEdit(QLineEdit):
                def __init__(self, *args, **kwargs):
                    QLineEdit.__init__(self, *args, **kwargs)
            
                    self.Vldatr = Validator(self)
                # Nothing within your code snippet did more than this
                # which does nothing but I assume your finished piece
                # makes that connection
            
            
            class DelayedValidatedLineEdit(QLineEdit):
                def __init__(self, *args, **kwargs):
                    QLineEdit.__init__(self, *args, **kwargs)
                    # Here is the semi-universal Validator
                    self.Vldatr = Validator(self)
            
                    # Here is the semi-universal Delayer
                    self.Delyr = Delayer()
                    self.textEdited.connect(self.Delyr.Restart)
            

            I got my UiLoader class from these sources:

            • https://robonobodojo.wordpress.com/2017/10/03/loading-a-pyside-ui-via-a-class/
            • https://robonobodojo.wordpress.com/2018/10/29/pyside2-widget-class-from-a-qt-designer-ui/
            • https://gist.github.com/fredrikaverpil/0a89b174c9d29bc585f11d250adf2a7c

            My UiLoader class:

            from PySide2.QtUiTools import QUiLoader
            
            
            def load_ui(ui_file, base_instance=None, custom_classes=()):
                loader = UiLoader(base_instance)
                for custom_class in custom_classes:
                    loader.registerCustomWidget(custom_class)
                loader.load(ui_file)
            
            
            class UiLoader(QUiLoader):
                def __init__(self, base_instance):
                    super().__init__()
                    self.base_instance = base_instance
            
                def createWidget(self, class_name, parent=None, name=''):
                    if parent is None and self.base_instance:
                        return self.base_instance
                    else:
                        return super().createWidget(class_name, parent, name)
            
            
            F Offline
            F Offline
            Flanagan
            wrote on last edited by
            #4

            And I fixed it, I have copied the code as is from the third link I put in one message above. Now it works.

            https://gist.github.com/fredrikaverpil/0a89b174c9d29bc585f11d250adf2a7c

            Now I can go in peace but against your recommendations xD

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved