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

java - Static nested class instance -

c# - Bluetooth LE CanUpdate Characteristic property -

JavaScript - Replace variable from string in all occurrences -