Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Avoiding garbage collection? [Solved]
Forum Updated to NodeBB v4.3 + New Features

Avoiding garbage collection? [Solved]

Scheduled Pinned Locked Moved General and Desktop
4 Posts 2 Posters 1.6k Views 1 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.
  • M Offline
    M Offline
    maclypse
    wrote on 17 Feb 2014, 12:32 last edited by
    #1

    So I'm trying to learn Python and PyQt4 at the same time, and I've sort of hit a little dead end while trying to build a simple test application. It's simply a menubar and a toolbar that will switch the central widget between two seperate text fields. Unfortunately, no matter how I try to avoid it - they get garbage collected as soon as you switch from one to the other, and I can't seem to find a nice way to prevent it. I've tried to keep the reference to the object, but it just doesn't seem to work. I'm guessing I'm simply going about this the wrong way and that there's a better way to achieve a simple functionality like this where you temporarily hide one element while displaying another. Can you point me in a better direction, please?

    Appending the test program, that doesn't work due to garbage collection.

    maclypse

    @#!/usr/bin/python

    -- coding: utf-8 --

    import sys
    from PyQt4 import QtGui

    class Example(QtGui.QMainWindow):

    def __init__(self):
        super(Example, self).__init__()
        self.initUI()
    
    def modeA(self):
        self.setCentralWidget(self.widgetA)
    
    def modeB(self):
        self.setCentralWidget(self.widgetB)
    
    def initUI(self):
        self.widgetA = QtGui.QTextEdit()
        self.widgetB = QtGui.QTextEdit()
        self.setCentralWidget(self.widgetA)
    
        exitAction = QtGui.QAction('Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(self.close)
    
        aAction = QtGui.QAction('Mode A', self)
        aAction.setStatusTip('Go to mode A')
        aAction.triggered.connect(self.modeA)
    
        bAction = QtGui.QAction('Mode B', self)
        bAction.setStatusTip('Go to mode B')
        bAction.triggered.connect(self.modeB)
    
        self.statusBar()
    
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(aAction)
        fileMenu.addAction(bAction)
        fileMenu.addAction(exitAction)
    
        toolbar = self.addToolBar('Tools')
        toolbar.addAction(aAction)
        toolbar.addAction(bAction)
        toolbar.addAction(exitAction)
    
        self.setGeometry(300, 300, 350, 250)
        self.setWindowTitle('Main window')
        self.show()
    

    def main():

    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())
    

    if name == 'main':
    main()
    @

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mmoll
      wrote on 17 Feb 2014, 14:17 last edited by
      #2

      The problem is that when you call setCentralWidget, the MainWindow becomes the parent of your widget and takes over ownership. The MainWindow is now responsible for destroying the widget at an appropriate time. You could probably use setParent to reparent the widget, but a look into the documentation of that function reveals the correct solution to your problem:

      [quote]
      Warning: It is very unlikely that you will ever need this function. If you have a widget that changes its content dynamically, it is far easier to use QStackedWidget.
      [/quote]

      1 Reply Last reply
      0
      • M Offline
        M Offline
        maclypse
        wrote on 17 Feb 2014, 14:29 last edited by
        #3

        Ahah! Yes, that sounds precisely like the thing I'm looking for! Thank you very much.

        I figured there was a nice and easy way to achieve the functionality without ever touching the central widget after it's been set. I just couldn't find it. :)

        maclypse

        1 Reply Last reply
        0
        • M Offline
          M Offline
          maclypse
          wrote on 17 Feb 2014, 14:43 last edited by
          #4

          For future reference in case anyone ever needs this again, this is functional version of it, using QStackedWidget. A nice and simple way to hide away one element and display another. Lovely.

          maclypse

          @#!/usr/bin/python

          -- coding: utf-8 --

          import sys
          from PyQt4 import QtGui

          class Example(QtGui.QMainWindow):
          def init(self):
          super(Example, self).init()
          self.initUI()

          def modeA(self):
              self.centralWidget().setCurrentIndex(0)
          
          def modeB(self):
              self.centralWidget().setCurrentIndex(1)
          
          def initUI(self):
              exitAction = QtGui.QAction('Exit', self)
              exitAction.setShortcut('Ctrl+Q')
              exitAction.setStatusTip('Exit application')
              exitAction.triggered.connect(self.close)
          
              aAction = QtGui.QAction('Mode A', self)
              aAction.setStatusTip('Go to mode A')
              aAction.triggered.connect(self.modeA)
          
              bAction = QtGui.QAction('Mode B', self)
              bAction.setStatusTip('Go to mode B')
              bAction.triggered.connect(self.modeB)
          
              self.statusBar()
          
              menubar = self.menuBar()
              fileMenu = menubar.addMenu('&File')
              fileMenu.addAction(aAction)
              fileMenu.addAction(bAction)
              fileMenu.addAction(exitAction)
          
              toolbar = self.addToolBar('Tools')
              toolbar.addAction(aAction)
              toolbar.addAction(bAction)
              toolbar.addAction(exitAction)
          
              a = QtGui.QTextEdit()
              b = QtGui.QTextEdit()
              cent = QtGui.QStackedWidget()
              cent.insertWidget(0, a)
              cent.insertWidget(1, b)
              self.setCentralWidget(cent)
          
              self.setGeometry(300, 300, 350, 250)
              self.setWindowTitle('Main window')
              self.show()
          

          def main():
          app = QtGui.QApplication(sys.argv)
          ex = Example()
          sys.exit(app.exec_())

          if name == 'main':
          main()@

          1 Reply Last reply
          0

          1/4

          17 Feb 2014, 12:32

          • Login

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