PyQt - 不显示FigureCanvas(导航工具栏可以)

时间:2017-03-22 16:51:07

标签: python qt matplotlib drag-and-drop pyqt

我正在尝试在FigureCanvas上实现拖放。这意味着,我想从左侧布局拖动文本并将其拖放到右侧的画布上。 不幸的是,即使显示导航工具栏,画布也不是。

在创建Create_Canvas类以实现拖放之前,我可以毫无问题地显示所有内容。我是编程的新手,我不确定我是否正确编写了Create_Canvas类。

我也张贴了一张照片:

enter image description here

如果您没有安装matplotlib。

提前致谢!

import sys, time

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure

import matplotlib.pyplot as plt
import matplotlib.cm as cm
import matplotlib.colors as mcolors
import matplotlib.colorbar as mcolorbar

import numpy as np
import pylab as pl

import random


class Example(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)
        self.editLayout = QWidget()
        self.edit = QLineEdit('chfghfghf', self)
        self.edit.setDragEnabled(True)

        self.left_layout = QVBoxLayout()
        self.left_layout.addWidget(self.edit)

        self.editLayout.setLayout(self.left_layout)

        #Create the right layout that contains the plot canvas.    
        self.plotLayout = QWidget();

        canvas = Create_Canvas(self)       

        self.button = QPushButton('Plot')

        # set the layout
        self.right_layout = QVBoxLayout()
        self.right_layout.addWidget(canvas)
        self.right_layout.addWidget(self.button)

        self.plotLayout.setLayout(self.right_layout)

        splitter_filebrowser = QSplitter(Qt.Horizontal)
        splitter_filebrowser.addWidget(self.editLayout)
        splitter_filebrowser.addWidget(self.plotLayout)
        splitter_filebrowser.setStretchFactor(1, 1)

        hbox = QHBoxLayout(self)
        hbox.addWidget(splitter_filebrowser)

        self.centralWidget().setLayout(hbox)

        self.setWindowTitle('Simple drag & drop')
        self.setGeometry(750, 100, 600, 500)


class Create_Canvas(QWidget):
    def __init__(self, parent):
        super().__init__(parent)
        self.setAcceptDrops(True)

        figure = plt.figure()
        canvas = FigureCanvas(figure)
        toolbar = NavigationToolbar(canvas, self)

        self.right_layout = QVBoxLayout()
        self.right_layout.addWidget(canvas)
        self.right_layout.addWidget(toolbar)

    def dragEnterEvent(self, e):
        print('entering')
        if e.mimeData().hasFormat('text/plain'):
            e.accept()
        else:
            e.ignore()

    def dragMoveEvent(self, e):
        print('drag moving')

    def dropEvent(self, e):
        print("dropped")


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    ex.show()
    app.exec_()      

2 个答案:

答案 0 :(得分:1)

重点是您需要将画布添加到布局并将此布局添加到窗口小部件。最后你也不应该忘记画画布。

class Create_Canvas(QWidget):
    def __init__(self, parent):
        QWidget.__init__(self,parent)
        self.setAcceptDrops(True)

        figure = plt.figure()
        self.canvas = FigureCanvas(figure)
        toolbar = NavigationToolbar(self.canvas, self)

        self.right_layout = QVBoxLayout()
        self.right_layout.addWidget(self.canvas)
        self.right_layout.addWidget(toolbar)
        # set the layout of this widget, otherwise the elements will not be seen.
        self.setLayout(self.right_layout)
        # plot some stuff
        self.ax = figure.add_subplot(111)
        self.ax.plot([1,2,5])        
        # finally draw the canvas
        self.canvas.draw()

(这是它在PyQt4中的样子,在PyQt5中应该类似)。

答案 1 :(得分:0)

在PyQt5中,您需要在主窗口类上使用super来接受放置。 dropevent函数应如下所示:

def dropEvent(self,e):
        """
        This function will enable the drop file directly on to the 
        main window. The file location will be stored in the self.filename
        """
        if e.mimeData().hasUrls:
            e.setDropAction(QtCore.Qt.CopyAction)
            e.accept()
            for url in e.mimeData().urls():
                if op_sys == 'Darwin':
                    fname = str(NSURL.URLWithString_(str(url.toString())).filePathURL().path())
                else:
                    fname = str(url.toLocalFile())
            self.filename = fname
            print("GOT ADDRESS:",self.filename)
            self.readData()
        else:
            e.ignore() # just like above functions  

完整的code给出以下输出: enter image description here