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. Debugging inconsistent QObject::setParent: Cannot set parent, new parent is in a different thread
Forum Updated to NodeBB v4.3 + New Features

Debugging inconsistent QObject::setParent: Cannot set parent, new parent is in a different thread

Scheduled Pinned Locked Moved Solved Qt for Python
11 Posts 3 Posters 2.6k Views 2 Watching
  • 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.
  • G gfinleyg

    I have a large project that I've been working on and I recently wanted to change a large QLabel into a series of rows of QLabels. I managed to get the class for it visually working the way I want it to, but inconsistently it crashes with only a few of the QLabels shown and a "QObject::setParent: Cannot set parent, new parent is in a different thread" error. Is there a way to see what components this error is related to exactly?

    I think it must have something to do with the self.qlabels[i].setText(txt) or self.qlabels[i].show() lines in the class, but when I run it standalone I can't get it to return any errors or crashes. In the larger part of the project I am calling setFullText from a different thread, but I haven't run into this problem before when setting things from other classes.

    I'm open to other ideas for moving things around or creating and deleting QLabels instead of hide/show, but this is the class code that came closest to working:

    from PyQt6.QtWidgets import QLabel, QWidget, QVBoxLayout
    #QWidget that reduces input text lines to fit a number of Qlabels in the widget's height
    #adds "..." at the top if lines are reduced and top is true
    #adds "...more" at the bottom if lines are reduced and top is false
    class LongVLabels(QWidget):
        def __init__(self, top=False):
            super(LongVLabels,self).__init__()
            self.top = top #boolean storing if the top of the text is shown (True) or the bottom (False)
            self.fullText = ""
            #two layouts in the widget, one to measure available size and one to store added widgets
            self.layoutMain = QVBoxLayout()
            self.layoutH = QVBoxLayout()
            #start with 100 widgets (QLabels), hidden
            self.widgetCount = 100
            self.qlabels = [QLabel() for x in range(self.widgetCount)]
            for x in self.qlabels:
                x.setStyleSheet("qproperty-indent:8;background-color:#ffc5d1;border-radius: 6px;")
                x.setFixedSize(500,18)
                self.layoutH.addWidget(x)
                x.hide()
            self.layoutMain.addLayout(self.layoutH)
            self.setLayout(self.layoutMain)
    
        def make_reduced_lines_text(self):
            #get the current line space available
            availableHeight = self.geometry().height()
            #hide any existing qlabels
            for x in self.qlabels:
                x.hide()
            reducedText = ""
            maxLines = int(availableHeight/24)
            splitText = self.fullText.split("\n") #number of lines for the box
            lenSplitText = len(splitText)
            if splitText == [""]:
                reducedText = "Almost done!"
            elif splitText == ["DONE"]:
                reducedText = ""
            elif lenSplitText < maxLines:
                #all the text fits, no need to adjust line count
                reducedText = self.fullText
            else:
                #text lines don't fit, resize
                if self.top:
                    reducedText = "\n".join(splitText[:maxLines-1]) + "\nmore...."
                else:
                    start = lenSplitText - maxLines + 2 #extra line space for the ellipsis
                    reducedText = "...\n" + "\n".join(splitText[start:])
    
            for i, txt in enumerate(reducedText.split("\n")):
                if i < self.widgetCount:
                    self.qlabels[i].setText(txt)
                    self.qlabels[i].show()
    
        def setFullText(self, textInput):
            self.fullText = textInput
            self.make_reduced_lines_text()
    
        def resizeEvent(self, event):
            self.make_reduced_lines_text()
    

    I'm running Windows10 with Python v3.10.11 and PyQt6 v6.7.0.

    jsulmJ Offline
    jsulmJ Offline
    jsulm
    Lifetime Qt Champion
    wrote on last edited by
    #2

    @gfinleyg said in Debugging inconsistent QObject::setParent: Cannot set parent, new parent is in a different thread:

    In the larger part of the project I am calling setFullText from a different thread

    Don't do that! It is not supported. Only UI/main thread may access UI stuff.
    If you want to trigger a change in the UI from another thread then emit a signal in that other thread and connect a slot in the main thread where you do the UI change.

    https://forum.qt.io/topic/113070/qt-code-of-conduct

    1 Reply Last reply
    3
    • G Offline
      G Offline
      gfinleyg
      wrote on last edited by
      #3

      Thanks for the quick response jsulm. I'll check out some other examples and see if I can figure out an easy way to interact with it using signals/slots.

      Any ideas on the other question I had or is that info not easily exposed?
      "QObject::setParent: Cannot set parent, new parent is in a different thread" error. Is there a way to see what components this error is related to exactly?

      jsulmJ 1 Reply Last reply
      0
      • G gfinleyg

        I have a large project that I've been working on and I recently wanted to change a large QLabel into a series of rows of QLabels. I managed to get the class for it visually working the way I want it to, but inconsistently it crashes with only a few of the QLabels shown and a "QObject::setParent: Cannot set parent, new parent is in a different thread" error. Is there a way to see what components this error is related to exactly?

        I think it must have something to do with the self.qlabels[i].setText(txt) or self.qlabels[i].show() lines in the class, but when I run it standalone I can't get it to return any errors or crashes. In the larger part of the project I am calling setFullText from a different thread, but I haven't run into this problem before when setting things from other classes.

        I'm open to other ideas for moving things around or creating and deleting QLabels instead of hide/show, but this is the class code that came closest to working:

        from PyQt6.QtWidgets import QLabel, QWidget, QVBoxLayout
        #QWidget that reduces input text lines to fit a number of Qlabels in the widget's height
        #adds "..." at the top if lines are reduced and top is true
        #adds "...more" at the bottom if lines are reduced and top is false
        class LongVLabels(QWidget):
            def __init__(self, top=False):
                super(LongVLabels,self).__init__()
                self.top = top #boolean storing if the top of the text is shown (True) or the bottom (False)
                self.fullText = ""
                #two layouts in the widget, one to measure available size and one to store added widgets
                self.layoutMain = QVBoxLayout()
                self.layoutH = QVBoxLayout()
                #start with 100 widgets (QLabels), hidden
                self.widgetCount = 100
                self.qlabels = [QLabel() for x in range(self.widgetCount)]
                for x in self.qlabels:
                    x.setStyleSheet("qproperty-indent:8;background-color:#ffc5d1;border-radius: 6px;")
                    x.setFixedSize(500,18)
                    self.layoutH.addWidget(x)
                    x.hide()
                self.layoutMain.addLayout(self.layoutH)
                self.setLayout(self.layoutMain)
        
            def make_reduced_lines_text(self):
                #get the current line space available
                availableHeight = self.geometry().height()
                #hide any existing qlabels
                for x in self.qlabels:
                    x.hide()
                reducedText = ""
                maxLines = int(availableHeight/24)
                splitText = self.fullText.split("\n") #number of lines for the box
                lenSplitText = len(splitText)
                if splitText == [""]:
                    reducedText = "Almost done!"
                elif splitText == ["DONE"]:
                    reducedText = ""
                elif lenSplitText < maxLines:
                    #all the text fits, no need to adjust line count
                    reducedText = self.fullText
                else:
                    #text lines don't fit, resize
                    if self.top:
                        reducedText = "\n".join(splitText[:maxLines-1]) + "\nmore...."
                    else:
                        start = lenSplitText - maxLines + 2 #extra line space for the ellipsis
                        reducedText = "...\n" + "\n".join(splitText[start:])
        
                for i, txt in enumerate(reducedText.split("\n")):
                    if i < self.widgetCount:
                        self.qlabels[i].setText(txt)
                        self.qlabels[i].show()
        
            def setFullText(self, textInput):
                self.fullText = textInput
                self.make_reduced_lines_text()
        
            def resizeEvent(self, event):
                self.make_reduced_lines_text()
        

        I'm running Windows10 with Python v3.10.11 and PyQt6 v6.7.0.

        jeremy_kJ Online
        jeremy_kJ Online
        jeremy_k
        wrote on last edited by
        #4

        @gfinleyg said in Debugging inconsistent QObject::setParent: Cannot set parent, new parent is in a different thread:

        I'm open to other ideas for moving things around or creating and deleting QLabels instead of hide/show, but this is the class code that came closest to working:

        What's the motivation for this change? It sounds like a significant pessimization.

        Asking a question about code? http://eel.is/iso-c++/testcase/

        1 Reply Last reply
        0
        • G Offline
          G Offline
          gfinleyg
          wrote on last edited by gfinleyg
          #5

          @jeremy_k I tried some other solutions that created the QLabel objects on the fly based on the number of lines rather than making 100 of them and hide/showing them selectively, that path seems to make more sense to me, but it also encountered the same crash earlier. It's only 57 lines of code anyway :)

          jeremy_kJ 1 Reply Last reply
          0
          • G gfinleyg

            @jeremy_k I tried some other solutions that created the QLabel objects on the fly based on the number of lines rather than making 100 of them and hide/showing them selectively, that path seems to make more sense to me, but it also encountered the same crash earlier. It's only 57 lines of code anyway :)

            jeremy_kJ Online
            jeremy_kJ Online
            jeremy_k
            wrote on last edited by
            #6

            @gfinleyg said in Debugging inconsistent QObject::setParent: Cannot set parent, new parent is in a different thread:

            @jeremy_k I tried some other solutions that created the QLabel objects on the fly based on the number of lines rather than making 100 of them and hide/showing them selectively, that path seems to make more sense to me, but it also encountered the same crash earlier. It's only 57 lines of code anyway :)

            It's not the creation and management of labels that I'm wondering about, but the decision to use more than one label (or QTextEdit/QPlainTextEdit/QTextBrowser) at all.

            Lines of code isn't a good measure of runtime efficiency. while true: pass is only 1 line, but I'm still waiting for it to complete...

            Asking a question about code? http://eel.is/iso-c++/testcase/

            1 Reply Last reply
            0
            • G Offline
              G Offline
              gfinleyg
              wrote on last edited by
              #7

              @jeremy_k I'm planning to set each QLabel's background color based on what was in the text. These won't be updated frequently while the code is running so I don't think the overhead will be that bad. I can always switch to the one QLabel with shortened text that I was using before if it turns out to be too cumbersome.

              jeremy_kJ 1 Reply Last reply
              0
              • G gfinleyg

                @jeremy_k I'm planning to set each QLabel's background color based on what was in the text. These won't be updated frequently while the code is running so I don't think the overhead will be that bad. I can always switch to the one QLabel with shortened text that I was using before if it turns out to be too cumbersome.

                jeremy_kJ Online
                jeremy_kJ Online
                jeremy_k
                wrote on last edited by
                #8

                @gfinleyg said in Debugging inconsistent QObject::setParent: Cannot set parent, new parent is in a different thread:

                @jeremy_k I'm planning to set each QLabel's background color based on what was in the text.

                This sounds like a use for rich text (aka html). The syntax highlighter example may be of help.

                Asking a question about code? http://eel.is/iso-c++/testcase/

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  gfinleyg
                  wrote on last edited by
                  #9

                  @jeremy_k I was looking at that, I'm also partial to the oval shape around the text that you can get with a QLabel and some styling. That may be another fallback though, thanks for the suggestion.

                  1 Reply Last reply
                  0
                  • G gfinleyg

                    Thanks for the quick response jsulm. I'll check out some other examples and see if I can figure out an easy way to interact with it using signals/slots.

                    Any ideas on the other question I had or is that info not easily exposed?
                    "QObject::setParent: Cannot set parent, new parent is in a different thread" error. Is there a way to see what components this error is related to exactly?

                    jsulmJ Offline
                    jsulmJ Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on last edited by
                    #10

                    @gfinleyg said in Debugging inconsistent QObject::setParent: Cannot set parent, new parent is in a different thread:

                    "QObject::setParent: Cannot set parent, new parent is in a different thread" error

                    Don't modify UI from other threads and you will not have this error...

                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    1
                    • G Offline
                      G Offline
                      gfinleyg
                      wrote on last edited by
                      #11

                      Yep, I got it working by adding some signal handling. I suppose if I run into another vague error I can ask about this again. Thanks!

                      1 Reply Last reply
                      0
                      • G gfinleyg has marked this topic as solved on

                      • Login

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