python 2.7 - How to make subclass of QStyledItemDelegate react properly on mouse hover in a QListView in PySide/PyQt? -


on way solve problems stated in earlier questions (question 1, question 2) alone, succeeded implement custom qstyleditemdelegate meets demands. here minimal working example illustrating current state:

import sys import pyside.qtcore core import pyside.qtgui gui   class dataref(object):      def __init__(self, i):         self.i =      def upperlabel(self):         return u'upperlabel {0}'.format(self.i)      def lowerlabel(self):         return u'lowerlabel {0}'.format(self.i)      def pixmap(self):         return gui.qpixmap(90, 90)  class mylistmodel(core.qabstractlistmodel):      def __init__(self, parent=none):         super(mylistmodel, self).__init__(parent)         self._items = [dataref(i) in range(20)]      def rowcount(self, parent=core.qmodelindex()):         return len(self._items)      def data(self, index, role=core.qt.displayrole):          if not index.isvalid():             return none          if role == core.qt.displayrole:             return self._items[index.row()]         return  class mylistdelegate(gui.qstyleditemdelegate):      w = 300     imsize = 90     pad = 5     h = imsize + 2*pad     sepx = 10      def __init__(self, parent=none):         super(mylistdelegate, self).__init__(parent)      def paint(self, painter, option, index):         mouseover = option.state in [73985, 73729]          if option.state & gui.qstyle.state_selected:             painter.fillrect(option.rect, painter.brush())          pen = painter.pen()         painter.save()          x,y = (option.rect.x(), option.rect.y())         dataref = index.data()         pixmap = dataref.pixmap()         upperlabel = dataref.upperlabel()         lowerlabel = dataref.lowerlabel()          if mouseover:             newpen = gui.qpen(core.qt.green, 1, core.qt.solidline)             painter.setpen(newpen)         else:             painter.setpen(pen)         painter.drawrect(x, y, self.w, self.h)         painter.setpen(pen)          x += self.pad         y += self.pad          painter.drawpixmap(x, y, pixmap)          font = painter.font()         textheight  = gui.qfontmetrics(font).height()          sx = self.imsize + self.sepx         sy = textheight/2          font.setbold(true)         painter.setfont(font)         painter.drawtext(x+sx, y-sy,                           self.w-self.imsize-self.sepx, self.imsize,                          core.qt.alignvcenter,                          upperlabel)         font.setbold(false)         font.setitalic(true)         painter.setfont(font)         painter.drawtext(x+sx, y+sy,                          self.w-self.imsize-self.sepx, self.imsize,                          core.qt.alignvcenter,                          lowerlabel)          painter.restore()      def sizehint(self, option, index):         return core.qsize(self.w, self.imsize+2*self.pad)      def editorevent(self, event, model, option, index):         if event.type() == core.qevent.mousebuttonrelease:             print 'clicked on item', index.row()         if event.type() == core.qevent.mousebuttondblclick:             print 'double-clicked on item', index.row()         return true  if __name__ == '__main__':       app = gui.qapplication(sys.argv)     app.setstylesheet('qlistview::item:hover {background: none;}')     mw = gui.qmainwindow()      model = mylistmodel()     view = gui.qlistview()     view.setitemdelegate(mylistdelegate(parent=view))     view.setspacing(5)     view.setmodel(model)      mw.setcentralwidget(view)     mw.show()      sys.exit(app.exec_()) 

i used dummy class dataref returns dummy labels , pixmap delegate. delegate rectangular outline pixmap @ left , 2 lines of formatted text @ right. 'editorevent' enables me detect clicks , double-clicks.

problems

the mylistdelegate.paint() function receives option.state values seem strange me. not correspond qstyle.state know. i'm using large int numbers got printing int(option.state). anyway: doesn't work quite well! lower border of frame not change it's color , strange things happen sometimes.

can show me better way that? optimally, using colors qstyle changing outline , background color, customizable using stylesheet?

any hints or explanations highly appreciated.

the value of option.state result of bitwise or operation of many qstyle.state flags.

to see if need draw mouseover state, need do:

if option.state & qstyle.state_mouseover:     # draw mouseover stuff else:     # don't draw mouse on stuff 

there may many other flags set, can choose handle or not writing similar if statements (all flags listed in c++ documentation linked above).

i suspect why seeing inconsistent behaviour. catching couple of mouseover state flags , ignoring times when other (unrelated) style flags set. suggest reading bitwise and-ing , or-ing learn why flags combined , extracted this, , you results large integers when print it.

finally, suspect lower border not changing colour because next item below drawing border on top of it. means calculation size of rectangle wrong. suggest doing debugging along lines see if can work out why.


Comments

Popular posts from this blog

javascript - Chart.js (Radar Chart) different scaleLineColor for each scaleLine -

apache - Error with PHP mail(): Multiple or malformed newlines found in additional_header -

java - Android – MapFragment overlay button shadow, just like MyLocation button -