The error "QObject :: startTimer: QTimer can only be used with threads started with QThread" many times when closing the application

I know this has been asked many times. I read all of these topics, and my case seems different. Everyone who has this problem has a few simple reasons why I think Ive been excluded, for example:

  • Starting a timer without starting an event loop
  • Starting / stopping a timer from a thread other than the one that created the timer
  • Inability to set the parent property of the widget, which will lead to problems with the order of destruction

Below I have a minimal sample code that demonstrates the problem. Please note that ive does not start threads or timers. I also set the parent element of each widget. If I remove the graph widgets, the problem will disappear, so the temptation is to blame pyQtGraph, however, if I turn on the plot widgets but exclude all empty tabs (i.e. each tab except tabCatchaTiger), the problem also disappears, and it seems to justifies pyQtGraph.

Versions:

  • Windows 7
  • Python 2.7.8
  • Wing IDE 5.0.9-1
  • PyQt 4.11.1
  • PyQwt 5.2.1
  • PyQtGraph 0.9.8

Test case:

from PyQt4 import Qt, QtGui, QtCore
import PyQt4.Qwt5 as Qwt
import pyqtgraph as pg

pg.functions.USE_WEAVE = False # Lets pyqtgraph plot without gcc

pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')

# GUI for visualizing data from database
class crashyGUI(QtGui.QWidget) :

    def __init__(self) :
        # Make the window
        QtGui.QWidget.__init__(self)
        self.resize(700, QtGui.QDesktopWidget().screenGeometry(self).height()*.85)
        self.setWindowTitle('Data Visualization')

        # Create tab interface
        tabWidget = QtGui.QTabWidget(self)

        # define the tab objects
        self.tabEeny = QtGui.QWidget(tabWidget)
        self.tabMeeny = QtGui.QWidget(tabWidget)
        self.tabMiney = QtGui.QWidget(tabWidget)
        self.tabMoe = QtGui.QWidget(tabWidget)
        self.tabCatchaTiger = QtGui.QWidget(tabWidget)
        self.tabByThe = QtGui.QWidget(tabWidget)
        self.tabToe = QtGui.QWidget(tabWidget)

        # Initialize the tab objects
        self.initTabCatchaTiger()

        ###########################################
        ############### Main Layout ###############
        ###########################################

        tabWidget.addTab(self.tabEeny, 'Eeny')
        tabWidget.addTab(self.tabMeeny, 'Meeny')
        tabWidget.addTab(self.tabMiney, 'Miney')
        tabWidget.addTab(self.tabMoe, 'Moe')
        tabWidget.addTab(self.tabCatchaTiger, 'Catch a Tiger')
        tabWidget.addTab(self.tabByThe, 'By The')
        tabWidget.addTab(self.tabToe, 'Toe')

        self.mainLayout = QtGui.QVBoxLayout(self)
        self.mainLayout.addWidget(tabWidget)

        self.setLayout(self.mainLayout)

    def initTabCatchaTiger(self):
        ###########################################
        ############# ADC Capture Tab #############
        ###########################################
        # define tab layout
        grid = QtGui.QGridLayout(self.tabCatchaTiger)

        # create copy of adc plot and add to row 3 of the grid
        self.catchaTigerPlot1 = pg.PlotWidget(name = 'Catch a Tiger 1', parent = self.tabCatchaTiger)
        self.catchaTigerPlot1.setTitle('Catch a Tiger 1')
        grid.addWidget(self.catchaTigerPlot1, 2, 0, 1, 8)

        self.catchaTigerPlot2 = pg.PlotWidget(name = 'Catch a Tiger 2', parent = self.tabCatchaTiger)
        self.catchaTigerPlot2.setTitle('Catch a Tiger 2')
        grid.addWidget(self.catchaTigerPlot2, 3, 0, 1, 8)

        # set layout for tab
        self.tabCatchaTiger.setLayout(grid)

    def closeEvent(self, event) :
            pass

def main() :
    # open a QApplication and dialog() GUI
    app = QtGui.QApplication([])

    windowCrashy = crashyGUI()
    windowCrashy.show()
    app.exec_()

main()
+5
source share
4 answers

Personally, I'm no longer trying to chase exit exits - just use pg.exit()and do with it.

( pyqtgraph, github)

0

.

Qt QObject::startTimer: QTimer can only be used with threads started with QThread .

( ) Qt QPixmap: Must construct a QApplication before a QPaintDevice, ​​ .

, python , .

__init__ :

    self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

QApplication.setQuitOnLastWindowClosed False, , Qt - python .

, , parent-child. , , , , PlotWidget, .

, , , PlotWidget . :

class PlotWidget(GraphicsView):
    ...
    def __init__(self, parent=None, background='default', **kargs):
        GraphicsView.__init__(self, parent, background=background)
        ...
        self.plotItem = PlotItem(**kargs)
        # make sure the item gets a parent
        self.plotItem.setParent(self)
        self.setCentralItem(self.plotItem)

QTimer .

+13

:

QApplication python. :

  • QTimer , pyqtgraph ViewBoxes QApplication.

  • , -, Qt/PyQt. :

    from PyQt4 import Qt, QtGui, QtCore
    
    def main() :
        app = QtGui.QApplication([])
        x = QtGui.QGraphicsView()
        s = QtGui.QGraphicsScene()
        x.setScene(s)
        x.show()
        app.exec_()
    
    main()
    

, global app QApplication .

+6

__init__:

self.setAttribute(Qt.WA_DeleteOnClose)
0

All Articles