Reproduce Python 2 PyQt4 QImage constructor behavior in Python 3 -


i have written small gui using pyqt4 displays image , gets point coordinates user clicks on. need display 2d numpy array grayscale, creating qimage array, creating qpixmap. in python 2 works fine.

when moved python 3, however, can't decide on constructor qimage - gives me following error:

typeerror: arguments did not match overloaded call:   qimage(): many arguments   qimage(qsize, qimage.format): argument 1 has unexpected type 'numpy.ndarray'   qimage(int, int, qimage.format): argument 1 has unexpected type 'numpy.ndarray'   qimage(str, int, int, qimage.format): argument 1 has unexpected type 'numpy.ndarray'   qimage(sip.voidptr, int, int, qimage.format): argument 1 has unexpected type 'numpy.ndarray'   qimage(str, int, int, int, qimage.format): argument 1 has unexpected type 'numpy.ndarray'   qimage(sip.voidptr, int, int, int, qimage.format): argument 1 has unexpected type 'numpy.ndarray'   qimage(list-of-str): argument 1 has unexpected type 'numpy.ndarray'   qimage(str, str format=none): argument 1 has unexpected type 'numpy.ndarray'   qimage(qimage): argument 1 has unexpected type 'numpy.ndarray'   qimage(object): many arguments 

as far can tell, qimage constructor calling 1 of these:

  • qimage(str, int, int, qimage.format)
  • qimage(sip.voidptr, int, int, qimage.format)

i'm assuming numpy array fits 1 of protocols necessary 1 of these. i'm thinking might have array versus view, variations i've tried either produce above error or make gui exit without doing anything. how can reproduce python 2 behavior in python 3?

the following small example, in same exact code works fine under python 2 not python 3:

from __future__ import (print_function, division)  pyqt4 import qtgui, qtcore import numpy np  class mouseview(qtgui.qgraphicsview):      mouseclick = qtcore.pyqtsignal(tuple)      def __init__(self, scene, parent=none):         super(mouseview, self).__init__(scene, parent=parent)      def mousepressevent(self, event):         self.mouseclick.emit((event.x(),                               self.scene().scenerect().height() - event.y()))   class simplepicker(qtgui.qdialog):      def __init__(self, data, parent=none):         super(simplepicker, self).__init__(parent)          mind = data.min()         maxd = data.max()         bdata = ((data - mind) / (maxd - mind) * 255.).astype(np.uint8)          wdims = data.shape         wid = wdims[0]         hgt = wdims[1]          # line of interest - works fine under python 2, not python 3         img = qtgui.qimage(bdata.t, wid, hgt,                            qtgui.qimage.format_indexed8)          self.scene = qtgui.qgraphicsscene(0, 0, wid, hgt)         self.px = self.scene.addpixmap(qtgui.qpixmap.fromimage(img))          view = mouseview(self.scene)         view.sethorizontalscrollbarpolicy(qtcore.qt.scrollbaralwaysoff)         view.setverticalscrollbarpolicy(qtcore.qt.scrollbaralwaysoff)         view.setsizepolicy(qtgui.qsizepolicy.fixed,                            qtgui.qsizepolicy.fixed)         view.setminimumsize(wid, hgt)         view.mouseclick.connect(self.click_point)          quitb = qtgui.qpushbutton("done")         quitb.clicked.connect(self.quit)          lay = qtgui.qvboxlayout()         lay.addwidget(view)         lay.addwidget(quitb)          self.setlayout(lay)          self.points = []      def click_point(self, xy):         self.points.append(xy)      def quit(self):         self.accept()   def test_picker():      x, y = np.mgrid[0:100, 0:100]     img = x * y      app = qtgui.qapplication.instance()     if app none:         app = qtgui.qapplication(['python'])      picker = simplepicker(img)     picker.show()     app.exec_()      print(picker.points)  if __name__ == "__main__":     test_picker() 

i using anaconda installation on windows 7 64-bit, qt 4.8.7, pyqt 4.10.4, numpy 1.9.2.

in pyqt constructor above, following behavior observed numpy array called bdata:

  • bdata works correctly both python 2 , python 3
  • bdata.t works 2, not 3 (constructor error)
  • bdata.t.copy() works both
  • bdata[::-1,:] not work either 2 or 3 (the same error)
  • bdata[::-1,:].copy() works both
  • bdata[::-1,:].base works both, loses result of reverse operation

as mentioned @ekhumoro in comments, need supports python buffer protocol. actual qt constructor of interest here this qimage constructor, or const version of it:

qimage(uchar * data, int width, int height, format format) 

from pyqt 4.10.4 documentation kept here, pyqt expects unsigned char * different in python 2 , 3:

python 2:

if qt expects char *, signed char * or unsigned char * (or const version) pyqt4 accept unicode or qstring contains ascii characters, str, qbytearray, or python object implements buffer protocol.

python 3:

if qt expects signed char * or unsigned char * (or const version) pyqt4 accept bytes.

a numpy array satisfies both of these, apparently numpy view doesn't satisfy either. it's baffling bdata.t works @ in python 2, purportedly returns view:

>>> = np.ones((2,3)) >>> b = a.t >>> b.base true 

the final answer: if need transformations result in view, can avoid errors doing copy() of result new array passing constructor. may not best answer, work.


Comments

Popular posts from this blog

Python Pandas join aggregated tables -

java - Static nested class instance -

process - Python What is the difference between a Pool of worker processes and just running multiple Processes? -