Frikster
Frikster

Reputation: 2903

Plot image in pyqt graphicsView using pyQtGraph

I tried reverse engineering the designerExample to get it doing the same thing that it does for a plot, but for an image but get two results, neither correct:

  1. If I promote my QGraphicsView to GraphicsView I get the image outputted but it is not movable or zoomable as you would expect from items in pyQtGraph (Run the examples script - I'm expecting similar behaviour to the GraphicsLayout example: there is an image in the grid in this example that is movable. Mine isn't even though I based my code off of this example)

enter image description here

enter image description here

  1. If I promote my QGraphicsView to GraphicsLayoutWidget I get AttributeError: 'QGraphicsView' object has no attribute 'addItem' which I can see in the debugger. However, what I cant see is in the debugger is the GraphicsView attribute that the GraphicsLayoutWidget should have. Also, the GraphicsView also doesn't have an addItem attribute, at least not according to what I can see when I navigate to ui.graphicsView in the debugger with the breakpoint set to just before the call to addItem(img)

Code:

import sys, os
import pyqtgraph as pg
import numpy as np
from PyQt4.QtGui import *

## Define main window class from template
path = os.path.dirname(os.path.abspath(__file__))
uiFile = os.path.join(path, 'pyQtGraphTest.ui')
WindowTemplate, TemplateBaseClass = pg.Qt.loadUiType(uiFile)

class QMainWindow(TemplateBaseClass):
    def __init__(self):
        #super(QtGui.QMainWindow, self).__init__(parent)
        TemplateBaseClass.__init__(self)

        self.ui = WindowTemplate()
        self.ui.setupUi(self)
        self.ui.pushButton.clicked.connect(self.do_it)

    def do_it(self):
        frame = np.random.normal(size=(100,100))
        img = pg.ImageItem(frame)
        self.ui.graphicsView.addItem(img) #BREAKPOINT HERE


if __name__ == '__main__':
    app = QApplication(sys.argv)

    form = QMainWindow()
    form.show()
    app.exec_()

pyQtGraphTest.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>632</width>
    <height>614</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>10</y>
      <width>99</width>
      <height>27</height>
     </rect>
    </property>
    <property name="text">
     <string>PushButton</string>
    </property>
   </widget>
   <widget class="GraphicsView" name="graphicsView">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>50</y>
      <width>571</width>
      <height>501</height>
     </rect>
    </property>
   </widget>
  </widget>
 </widget>
 <customwidgets>
  <customwidget>
   <class>GraphicsView</class>
   <extends>QGraphicsView</extends>
   <header>pyqtgraph.h</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

Upvotes: 1

Views: 10175

Answers (1)

segFaultCoder
segFaultCoder

Reputation: 476

Referencing back to the example you quote, GraphicsLayout, the sequence of events they perform are:

  1. create a GraphicsView
  2. create a GraphicsLayout
  3. set GraphicsLayout object as GraphicsView central item
  4. get a ViewBox reference via a GraphicsLayout.addViewBox
  5. create an image
  6. add the image to the ViewBox

Your code leaves out steps 2 through 4, and you add the image directly to the GraphicsView (since you didn't create a ViewBox, where the image wants to be).

If for instance you decided to promote a GraphicsLayoutWidget in Designer, that would also work, but then you should reference the Plotting.py example for the proper sequence to add the image. The Plotting.py example starts with a call to pg.GraphicsWindow(), which subclasses GraphicsLayoutWidget.

Here's the fixes as required for your running example.

class QMainWindow(TemplateBaseClass):
def __init__(self):
    #super(QtGui.QMainWindow, self).__init__(parent)
    TemplateBaseClass.__init__(self)

    self.ui = WindowTemplate()
    self.ui.setupUi(self)
    self.ui.pushButton.clicked.connect(self.do_it)
    self.glayout = pg.GraphicsLayout()
    self.vb = self.glayout.addViewBox()

def do_it(self):
    frame = np.random.normal(size=(100,100))
    img = pg.ImageItem(frame)
    self.ui.graphicsView.setCentralItem(self.glayout)
    self.vb.addItem(img)
    self.vb.autoRange()
    #self.ui.graphicsView.addItem(img) #BREAKPOINT HERE

Upvotes: 1

Related Questions