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
Post a Comment