问题描述
正在使用带有嵌入式matplotlib图的多线程pyqt应用程序工作,但突然遇到了一个奇怪的问题:无法在QWidget上绘制工具栏。我认为pyqt对象继承存在问题:据我了解-我有“ mainwindow”小部件(QWidget),它是Canvas的父级“ plotwidget”对象(QWidget)的父级。因此,要添加工具栏,我应该调用NavigationToolbar(self.canvas,self.plotwidget),但是很遗憾,它没有给我任何东西。这是我的代码:
from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.QtCore import QRunnable,QThreadPool
from PyQt5.QtCore import *
import queue as Queue
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas,NavigationToolbar2QT as NavigationToolbar
import sys
class Worker(QRunnable):
def __init__(self,queue):
QRunnable.__init__ ( self )
self.queue = queue
@pyqtSlot()
def run(self):
self.queue.put ( create_graph() )
class Canvas ( FigureCanvas ):
def __init__(self,parent,figure):
self.fig = figure
FigureCanvas.__init__ ( self,self.fig )
self.setParent ( parent )
class GUI (QtWidgets.QMainWindow):
fig,axes = plt.subplots ( 1,1,figsize = (2,2))
def __init__(self):
super().__init__()
self.setupUi(self)
def setupUi(self,MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1800,900)
MainWindow.move(40,20)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.plotwidget = QtWidgets.QWidget(self.centralwidget)
self.plotwidget.setGeometry ( QtCore.QRect ( 30,400,811,381) )
self.plotwidget.setParent ( self.centralwidget )
plt.scatter ( [0,2,3,4,5],[3,11,15,19] )
self.canvas = Canvas(self,GUI.fig)
self.canvas.setGeometry ( QtCore.QRect ( 30,1000 ) )
self.canvas.setParent ( self.plotwidget )
self.toolbar = NavigationToolbar ( self.canvas,self.plotwidget )
MainWindow.setCentralWidget(self.centralwidget)
self.scroll = QtWidgets.QScrollArea(self.centralwidget)
self.scroll.setGeometry ( QtCore.QRect ( 30,381 ) )
self.scroll.setWidget(self.canvas)
def startCalc(self):
self.queue = Queue.Queue ()
self.threadpool = QThreadPool ()
print ( "Multithreading with maximum %d threads" % self.threadpool.maxThreadCount () )
worker = Worker (self.queue)
self.threadpool.start ( worker )
QtCore.QTimer.singleShot ( 500,self.process_queue )
def process_queue(self):
try:
self.canvas.draw ()
except Queue.Empty:
QtCore.QTimer.singleShot ( 500,self.process_queue )
def main():
global window
app = QtWidgets.QApplication ( sys.argv )
window = GUI ()
window.show ()
try:
sys.exit ( app.exec_ () )
except:
print ( "Exiting" )
if __name__ == '__main__':
main () # то запускаем функцию main()
解决方法
对不起,如果您在示例中未调用它们,我不知道为什么显示startCalc
和process_queue
方法?试试吧:
import sys
#import queue as Queue
from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.QtCore import QRunnable,QThreadPool
from PyQt5.QtCore import pyqtSlot
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas,\
NavigationToolbar2QT as NavigationToolbar
class Canvas(FigureCanvas):
def __init__(self,parent,figure):
self.fig = figure
FigureCanvas.__init__(self,self.fig)
self.setParent(parent)
class GUI(QtWidgets.QMainWindow):
fig,axes = plt.subplots(1,1,figsize=(2,2))
def __init__(self):
super().__init__()
# self.setupUi(self)
self.initUi()
# def setupUi(self,MainWindow):
def initUi(self):
self.centralwidget = QtWidgets.QWidget(self)
self.setCentralWidget(self.centralwidget)
plt.scatter([0,2,3,4,5],[3,11,15,19])
self.canvas = Canvas(self,GUI.fig)
self.toolbar = NavigationToolbar(self.canvas,self)
self.axes.set(xlabel='time (s)',ylabel='voltage (mV)',title='About as simple ...')
self.axes.grid()
layout = QtWidgets.QVBoxLayout(self.centralwidget)
layout.addWidget(self.canvas)
layout.addWidget(self.toolbar)
def main():
# global window
app = QtWidgets.QApplication ( sys.argv )
window = GUI()
window.resize(640,480)
window.show()
# try:
sys.exit(app.exec_())
# except:
# print("Exiting")
if __name__ == '__main__':
main ()