[PyQt] Hover Event for a QGraphicsItem
sw33tz
nyavuz.nm20 at gmail.com
Sun May 8 15:32:43 BST 2016
So i have a toggle bar and you add the switch object from there and also I
can connect switch objects with lines but because of the self
.setAcceptHoverEvents(True) command when I click the switch object and try
to connect it to another one and then release my mouse the line does not
land on that object. When I erase this command everything goes back to
normal, but I still cant get the hoverEnterEvent function to be triggered.
# ---------------SWITCH OBJECT CLASS---------------#
*class **switch_Object*(QtGui.QGraphicsPixmapItem):
*def *__init__(self, parent=None):
super(switch_Object, self).__init__(parent)
pixmap = QtGui.QPixmap("switch.png").scaled(40, 40,
QtCore.Qt.KeepAspectRatio)
self.setPixmap(pixmap)
self.setFlag(QtGui.QGraphicsPixmapItem.ItemIsSelectable)
self.setFlag(QtGui.QGraphicsPixmapItem.ItemIsMovable)
self.setAcceptHoverEvents(True)
self.switch_LinkedWithItems = []
*def **hoverEnterEvent*(self, event):
*print *'hello'
# ---------------SCENE CLASS---------------#
*class **graphicsScene*(QtGui.QGraphicsScene):
*def *__init__(self, parent=None):
super(graphicsScene, self).__init__(parent)
self.i = 0
self.setSceneRect(-180, -90, 360, 180)
self.pen = QtGui.QPen(QtCore.Qt.black, 3, QtCore.Qt.SolidLine)
self.selected_Object = None
*global *selected
selected = 0
# ---------------MOUSE CLICK EVENT---------------#
*def **mousePressEvent*(self, event):
*global *switch_cs
*global *selected
# Unselect the previous selected item when a new item is being
selected
*for *selected_items *in *selected_items_list:
selected_items.setSelected(False)
selected_items_list.remove(selected_items)
# Get position of the mouse click and set a rectangle for the
collision test
self.cursorPosition = event.scenePos()
rect = QtCore.QRectF(self.cursorPosition.x(),self.cursorPosition.y(),
40, 40)
intersection_list = self.items(rect)
# ---------------CREATE SWITCH ITEM---------------#
*if *switch_cs == 1 *or *connectLine_cs == 1:
# Test if there is a switch in the scene
*if *len(switchObject_list) == 0:
self.switch_item = switch_Object()
switchObject_list.append(self.switch_item)
# Test if there is a collision between graphic items when
selecting item
*elif *len(intersection_list):
*for *switch *in *switchObject_list:
*if *switch == intersection_list[len(intersection_list)
- 1]:
self.selected_Object = switch
selected_items_list.append(intersection_list[len(intersection_list)
- 1])
*if *connectLine_cs == 1 *and *self.selected_Object *is not
*None:
self.cursorStartPosition = event.scenePos()
self.start = QtCore.QPoint(self.cursorStartPosition.x(),
self.cursorStartPosition.y())
intersection_list[len(intersection_list) - 1].setSelected(
True)
selected = 1
# If there is no collision then create new switch item
*else*:
self.switch_item = switch_Object()
selected = 0
switchObject_list.append(self.switch_item)
# ---------------MOUSE DRAG EVENT---------------#
*def **mouseMoveEvent*(self, event):
*if *connectLine_cs == 1:
*if *self.start:
self.cursorCurrentPosition = event.scenePos()
self.current = QtCore.QPointF(self.cursorCurrentPosition.x()
,self.cursorCurrentPosition.y())
self.draw_line(self.current)
rect_for_link = QtCore.QRectF(self.cursorCurrentPosition.x()
,self.cursorCurrentPosition.y(), 30, 30)
# Check for any collision when drawing the line
self.intersection_forLink_list = self.items(rect_for_link)
# ---------------Draw line for animated effect---------------#
*def **draw_line*(self, pos):
*try*:
# remove the old line if exists
self.removeItem(self.line)
*except*:
*pass *self.line = QtGui.QGraphicsLineItem(QtCore.QLineF(self.start,
pos))
self.line.setPen(self.pen)
self.addItem(self.line)
*def **mouseReleaseEvent*(self, event):
# ---------------ADD SWITCH ITEM TO SCENE IF SWITCH TOOLBAR HAS
BEEN SELECTED---------------#
*if *switch_cs == 1:
*if *selected == 0:
self.addItem(self.switch_item)
self.switch_item.setPos(event.scenePos())
# ---------------ADD LINE ITEM TO SCENE IF LINE TOOLBAR HAS BEEN
SELECTED---------------#
*if *connectLine_cs == 1:
lineItem_list.append(self.line)
*for *link *in *lineItem_list:
self.addItem(link)
# Check if there has been a collision with another item when
drawing a line
*if *len(self.intersection_forLink_list) > 0:
# iterate in switchObject_list and check to see if the
objects graphical item is the collided item
*for *switch_objects *in *switchObject_list:
*if *switch_objects == self
.intersection_forLink_list[len(self.intersection_forLink_list)-1]:
# Add the item that has been linked with the
switch
self
.selected_Object.switch_LinkedWithItems.append(switch_objects)
self.intersection_forLink_list = []
On Sun, May 8, 2016 at 5:04 PM, Elvis Stansvik [via Python] <
ml-node+s6n5190337h58 at n6.nabble.com> wrote:
> 2016-05-08 16:06 GMT+02:00 Elvis Stansvik <[hidden email]
> <http:///user/SendEmail.jtp?type=node&node=5190337&i=0>>:
>
> > 2016-05-08 15:24 GMT+02:00 sw33tz <[hidden email]
> <http:///user/SendEmail.jtp?type=node&node=5190337&i=1>>:
> >> By the way I'm not posting the entire code so sometimes I might forget
> to
> >> change the name of a variable or class but in my original code the
> format is
> >> written correctly.
> >
> > In general, http://sscce.org/ is very good advice.
> >
> > When you send an example which the reader you seek help from cannot
> > run, it puts an extra burden on that person, because he/she will often
> > have to fix up the example and run it in order to help.
> >
> > I'm not going to borther doing that this time, but see my comments
> > inline below, which are at best educated guesses since the code you
> > have given won't run.
>
> That sounded a bit harsch, I'm sorry for that.
>
> But it's so much easier for us to help if you send the code exactly as
> it is, even if it's only parts of it.
>
> The code you sent in your last email could not possibly have been the
> one you were trying to run, since in your mouseReleaseEvent you try to
> access self.graphics_item.graphics_pixItem, which doesn't even exist
> anymore in the graphics_Object class, so you would have gotten an
> error.
>
> I know it's a bit of work cut your code down a minimal working example
> that shows the problem you're having, but doing so makes it much
> easier to help, and the chances are great that you find the problem on
> your own when doing so.
>
> Elvis
>
> >
> >>
> >> On Sun, May 8, 2016 at 4:34 PM, Nesibe Yavuz <[hidden email]> wrote:
> >>>
> >>> So I rewrote what you suggested but I'm still not being able to detect
> the
> >>> hover event...why is this working?
> >>>
> >>> class graphics_Object(QtGui.QGraphicsPixmapItem):
> >>> def __init__(self, parent=None):
> >>> super(graphics_Object, self).__init__(parent)
> >>> pixmap = QtGui.QPixmap("switch.png").scaled(40, 40,
> >>> QtCore.Qt.KeepAspectRatio)
> >>> self.setPixmap(pixmap)
> >>> self.setFlag(QtGui.QGraphicsPixmapItem.ItemIsSelectable)
> >>> self.setFlag(QtGui.QGraphicsPixmapItem.ItemIsMovable)
> >>> self.setAcceptHoverEvents(True)
> >>> self.switch_LinkedWithItems = []
> >>> self.switch_mininet_name = ''
> >>>
> >>> def hoverEnterEvent(self, event):
> >>> print 'hello'
> >>>
> >>> def hoverLeaveEvent(self, event):
> >>> print 'goodbye'
> >>>
> >>> class graphicsScene(QtGui.QGraphicsScene):
> >>> def __init__(self, parent=None):
> >>> super(graphicsScene, self).__init__(parent)
> >>>
> >>> def mousePressEvent(self, event):
> >>> self.graphics_item = graphics_Object()
> >>>
> >>> def mouseReleaseEvent(self, event)
> >>> self.addItem(self.graphics_item.graphics_pixItem)
> >
> > You're still doing something strange here if this is indeed your
> > current code. Why are you (seemingly) keeping one graphics item as an
> > attribute of another? That doesn't make sense, and it's probably still
> > the case that the item you're adding is not of type graphics_Object,
> > which is the class where you are overriding hoverEnterEvent /
> > hoverLeaveEvent.
> >
> > From the looks of it, you've fixed everything but the issue I pointed
> > out as the main one.
> >
> > Elvis
> >
> >>> self.graphics_item.setPos(event.scenePos())
> >>>
> >>>
> >>> class Form(QtGui.QMainWindow):
> >>> def __init__(self):
> >>> super(Form, self).__init__()
> >>> self.ui = uic.loadUi('form.ui')
> >>>
> >>> self.scene = graphicsScene()
> >>> self.setMouseTracking(True)
> >>>
> >>>
> >>>
> >>>
> >>> On Sun, May 8, 2016 at 1:54 PM, Elvis Stansvik [via Python] <[hidden
> >>> email]> wrote:
> >>>>
> >>>> 2016-05-07 23:05 GMT+02:00 sw33tz <[hidden email]>:
> >>>> > Thanks for replying...I've updated my code but I still cant get it
> to
> >>>> > work:
> >>>>
> >>>> I've now had a closer look at your code. There are several problems
> >>>> with which I point out inline below.
> >>>>
> >>>> >
> >>>> > class graphics_Object(QtGui.QGraphicsPixmapItem):
> >>>> > def __init__(self, parent=None):
> >>>> > super(switch_Object, self).__init__(parent)
> >>>>
> >>>> This, as I already mentioned, should be graphics_Object and not
> >>>> graphics_Object in the call to super(..).
> >>>>
> >>>> > pixmap = QtGui.QPixmap("item.png")
> >>>> > self.graphics_pixItem =
> >>>> > QtGui.QGraphicsPixmapItem(pixmap.scaled(40,
> >>>> > 40, QtCore.Qt.KeepAspectRatio))
> >>>> >
> >>>> >
> >>>> >
> self.graphics_pixItem.setFlag(QtGui.QGraphicsPixmapItem.ItemIsSelectable)
> >>>> >
> >>>> >
> self.graphics_pixItem.setFlag(QtGui.QGraphicsPixmapItem.ItemIsMovable)
> >>>> > self.graphics_pixItem.setAcceptHoverEvents(True)
> >>>> >
> >>>> >
> >>>> > def hoverEnterEvent(self, event):
> >>>> > print 'hello'
> >>>> Here's your real problem, you are overriding hoverEnterEvent in the
> >>>> graphics_Object class, but the item that you are later adding to the
> >>>> scene is self.graphics_pixItem, which is of type
> >>>> QtGui.QGraphicsPixmapItem.
> >>>>
> >>>> >
> >>>> > class graphicsScene(QtGui.QGraphicsScene):
> >>>> > def __init__(self, parent=None):
> >>>> > super(graphicsScene, self).__init__(parent)
> >>>> >
> >>>> > def mousePressEvent(self, event):
> >>>> > self.graphics_item = graphics_Object()
> >>>> > def mouseReleaseEvent(self, event)
> >>>>
> >>>> There's a missing ':' above.
> >>>>
> >>>> > self.addItem(self.self.graphics_item.graphics_pixItem)
> >>>>
> >>>> Apart from "self.self" which makes no sense (it should be just
> >>>> "self.graphics_item"), here you are adding graphics_pixItem to the
> >>>> scene, which is of type QtGui.QGraphicsPixmapItem, not of type
> >>>> graphics_Object.
> >>>>
> >>>> You seem to have a misunderstanding of how inheritance vs composition
> >>>> works.
> >>>>
> >>>> >
> >>>> > self.graphics_item.self.graphics_pixItem.setPos(event.scenePos())
> >>>>
> >>>> Here's again a strange use of "self" which will give an error. `self`
> >>>> is only available from within the class itself, the
> >>>> "self.graphics_item.self" here should be just "self.graphics_item".
> >>>>
> >>>> Here's roughly how I would structure the code, given what I've seen
> in
> >>>> your example (Python 2, PyQt 4, since I'm guessing that's what you
> >>>> use):
> >>>>
> >>>>
> >>>> main.py:
> >>>>
> >>>> from sys import argv, exit
> >>>>
> >>>> from PyQt4.QtGui import QApplication
> >>>> from PyQt4.QtGui import QGraphicsItem
> >>>> from PyQt4.QtGui import QGraphicsPixmapItem
> >>>> from PyQt4.QtGui import QGraphicsScene
> >>>> from PyQt4.QtGui import QMainWindow
> >>>> from PyQt4.QtGui import QPixmap
> >>>> from PyQt4.QtCore import Qt
> >>>> from PyQt4.uic import loadUi
> >>>>
> >>>>
> >>>> class Item(QGraphicsPixmapItem):
> >>>>
> >>>> def __init__(self, parent=None):
> >>>> super(Item, self).__init__(parent)
> >>>>
> >>>> pixmap = QPixmap('item.png').scaled(40, 40,
> Qt.KeepAspectRatio)
> >>>>
> >>>> self.setPixmap(pixmap)
> >>>> self.setFlag(QGraphicsItem.ItemIsSelectable)
> >>>> self.setFlag(QGraphicsItem.ItemIsMovable)
> >>>> self.setAcceptHoverEvents(True)
> >>>>
> >>>> def hoverEnterEvent(self, event):
> >>>> print('hover enter') # Do whatever you need to do here
> >>>>
> >>>> def hoverLeaveEvent(self, event):
> >>>> print('hover leave') # Do whatever you need to do here
> >>>>
> >>>>
> >>>> class Scene(QGraphicsScene):
> >>>>
> >>>> def __init__(self, parent=None):
> >>>> super(Scene, self).__init__(parent)
> >>>>
> >>>> def mouseReleaseEvent(self, event):
> >>>> item = Item()
> >>>> item.setPos(event.scenePos())
> >>>> self.addItem(item)
> >>>>
> >>>>
> >>>> class Window(QMainWindow):
> >>>>
> >>>> def __init__(self, parent=None):
> >>>> super(Window, self).__init__(parent)
> >>>>
> >>>> loadUi('window.ui'), self)
> >>>>
> >>>> self.scene = Scene(self)
> >>>> self.view.setScene(self.scene)
> >>>>
> >>>>
> >>>> app = None
> >>>>
> >>>>
> >>>> def main():
> >>>> global app
> >>>>
> >>>> app = QApplication(argv)
> >>>>
> >>>> window = Window()
> >>>> window.show()
> >>>>
> >>>> exit(app.exec_())
> >>>>
> >>>>
> >>>> if __name__ == '__main__':
> >>>> main()
> >>>>
> >>>>
> >>>> window.ui:
> >>>>
> >>>> <?xml version="1.0" encoding="UTF-8"?>
> >>>> <ui version="4.0">
> >>>> <class>Window</class>
> >>>> <widget class="QMainWindow" name="Window">
> >>>> <property name="geometry">
> >>>> <rect>
> >>>> <x>0</x>
> >>>> <y>0</y>
> >>>> <width>800</width>
> >>>> <height>600</height>
> >>>> </rect>
> >>>> </property>
> >>>> <property name="windowTitle">
> >>>> <string>MainWindow</string>
> >>>> </property>
> >>>> <widget class="QWidget" name="centralwidget">
> >>>> <layout class="QVBoxLayout" name="verticalLayout">
> >>>> <item>
> >>>> <widget class="QGraphicsView" name="view"/>
> >>>> </item>
> >>>> </layout>
> >>>> </widget>
> >>>> </widget>
> >>>> <resources/>
> >>>> <connections/>
> >>>> </ui>
> >>>>
> >>>>
> >>>> Hope you can use that as starting point / inspiration and figure out
> >>>> things from there.
> >>>>
> >>>> Elvis
> >>>>
> >>>> >
> >>>> > class Form(QtGui.QMainWindow):
> >>>>
> >>>> > def __init__(self):
> >>>> > super(Form, self).__init__()
> >>>> > self.ui = uic.loadUi('form.ui')
> >>>> >
> >>>> > self.scene = graphicsScene()
> >>>> > self.ui.view.setScene(self.scene)
> >>>> >
> >>>> > self.setMouseTracking(True)
> >>>> >
> >>>> >
> >>>> > On Sat, May 7, 2016 at 10:55 PM, Elvis Stansvik [via Python]
> <[hidden
> >>>>
> >>>> > email]> wrote:
> >>>> >>
> >>>> >> Hi Nesibe,
> >>>> >>
> >>>> >> 2016-05-07 19:46 GMT+02:00 sw33tz <[hidden email]>:
> >>>> >> > I want some small text to pop up when I have my curser over a
> >>>> >> > QGraphicsItem
> >>>> >> > in my QGraphicsScene. I have a class that inherits from
> >>>> >> > QGraphicsItem,
> >>>> >> > and
> >>>> >> > this represents my graphical items in the scene.
> >>>> >> >
> >>>> >> > I tried using the QGraphicsItem.hoverEnterEvent and I also set
> the
> >>>> >> > setAcceptHoverEvents(True), but I still can't enable that hover
> >>>> >> > event. I
> >>>> >> > also came across an event filter method but I'm not sure where
> to
> >>>> >> > implement
> >>>> >> > it.
> >>>> >>
> >>>> >> This seems to work here:
> >>>> >>
> >>>> >>
> >>>> >> test.py:
> >>>> >>
> >>>> >> from sys import argv, exit
> >>>> >>
> >>>> >> from PyQt5.QtCore import Qt
> >>>> >> from PyQt5.QtWidgets import QApplication
> >>>> >> from PyQt5.QtWidgets import QGraphicsEllipseItem
> >>>> >> from PyQt5.QtWidgets import QGraphicsScene
> >>>> >> from PyQt5.QtWidgets import QGraphicsView
> >>>> >> from PyQt5.QtWidgets import QMainWindow
> >>>> >>
> >>>> >>
> >>>> >> class MyItem(QGraphicsEllipseItem):
> >>>> >>
> >>>> >> def __init__(self, parent=None):
> >>>> >> super(MyItem, self).__init__(parent)
> >>>> >>
> >>>> >> self.setRect(50, 50, 50, 50)
> >>>> >> self.setBrush(Qt.red)
> >>>> >> self.setAcceptHoverEvents(True)
> >>>> >>
> >>>> >> def hoverEnterEvent(self, event):
> >>>> >> print('hover enter')
> >>>> >>
> >>>> >> def hoverLeaveEvent(self, event):
> >>>> >> print('hover leave')
> >>>> >>
> >>>> >>
> >>>> >> app = None
> >>>> >>
> >>>> >>
> >>>> >> def main():
> >>>> >> global app
> >>>> >>
> >>>> >> app = QApplication(argv)
> >>>> >>
> >>>> >> scene = QGraphicsScene()
> >>>> >> scene.addItem(MyItem())
> >>>> >>
> >>>> >> view = QGraphicsView()
> >>>> >> view.setScene(scene)
> >>>> >>
> >>>> >> window = QMainWindow()
> >>>> >> window.setCentralWidget(view)
> >>>> >> window.show()
> >>>> >>
> >>>> >> exit(app.exec_())
> >>>> >>
> >>>> >>
> >>>> >> if __name__ == '__main__':
> >>>> >> main()
> >>>> >>
> >>>> >>
> >>>> >> Hope that helps.
> >>>> >>
> >>>> >> Best regards,
> >>>> >> Elvis
> >>>> >>
> >>>> >> >
> >>>> >> > Should I install the event filter in the QGraphicsItem class, or
> the
> >>>> >> > scene?
> >>>> >> > I tried both and I'm still not getting the desired result. I
> want to
> >>>> >> > be
> >>>> >> > able
> >>>> >> > to hover over all the items in the scene.
> >>>> >> >
> >>>> >> >
> >>>> >> > class HoverEventFilter(QtCore.QObject):
> >>>> >> > def eventFilter(self, receiver, event):
> >>>> >> > if (event.type() == QtCore.QEvent.HoverEnter):
> >>>> >> > # this is for test purposes
> >>>> >> > print 'hover event'
> >>>> >> > return True
> >>>> >> > else:
> >>>> >> > # Call Base Class Method to Continue Normal Event
> >>>> >> > Processing
> >>>> >> > return super(HoverEventFilter,
> >>>> >> > self).eventFilter(receiver,
> >>>> >> > event)
> >>>> >> >
> >>>> >> >
> >>>> >> >
> >>>> >> > --
> >>>> >> > View this message in context:
> >>>> >> >
> >>>> >> >
> http://python.6.x6.nabble.com/Hover-Event-for-a-QGraphicsItem-tp5190283.html
> >>>> >> > Sent from the PyQt mailing list archive at Nabble.com.
> >>>> >> > _______________________________________________
> >>>> >> > PyQt mailing list [hidden email]
> >>>> >> > https://www.riverbankcomputing.com/mailman/listinfo/pyqt
> >>>> >> _______________________________________________
> >>>> >> PyQt mailing list [hidden email]
> >>>> >> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
> >>>> >>
> >>>> >> ________________________________
> >>>> >> If you reply to this email, your message will be added to the
> >>>> >> discussion
> >>>> >> below:
> >>>> >>
> >>>> >>
> >>>> >>
> http://python.6.x6.nabble.com/Hover-Event-for-a-QGraphicsItem-tp5190283p5190286.html
> >>>> >> To unsubscribe from Hover Event for a QGraphicsItem, click here.
> >>>> >> NAML
> >>>> >
> >>>> >
> >>>> >
> >>>> > ________________________________
> >>>> > View this message in context: Re: Hover Event for a QGraphicsItem
> >>>> >
> >>>> > Sent from the PyQt mailing list archive at Nabble.com.
> >>>> >
> >>>> > _______________________________________________
> >>>> > PyQt mailing list [hidden email]
> >>>> > https://www.riverbankcomputing.com/mailman/listinfo/pyqt
> >>>> _______________________________________________
> >>>> PyQt mailing list [hidden email]
> >>>> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
> >>>>
> >>>> ________________________________
> >>>> If you reply to this email, your message will be added to the
> discussion
> >>>> below:
> >>>>
> >>>>
> http://python.6.x6.nabble.com/Hover-Event-for-a-QGraphicsItem-tp5190283p5190318.html
> >>>> To unsubscribe from Hover Event for a QGraphicsItem, click here.
> >>>> NAML
> >>>
> >>>
> >>
> >>
> >> ________________________________
> >> View this message in context: Re: Hover Event for a QGraphicsItem
> >> Sent from the PyQt mailing list archive at Nabble.com.
> >>
> >> _______________________________________________
> >> PyQt mailing list [hidden email]
> <http:///user/SendEmail.jtp?type=node&node=5190337&i=2>
> >> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
> _______________________________________________
> PyQt mailing list [hidden email]
> <http:///user/SendEmail.jtp?type=node&node=5190337&i=3>
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
>
> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>
> http://python.6.x6.nabble.com/Hover-Event-for-a-QGraphicsItem-tp5190283p5190337.html
> To unsubscribe from Hover Event for a QGraphicsItem, click here
> <http://python.6.x6.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=5190283&code=bnlhdnV6Lm5tMjBAZ21haWwuY29tfDUxOTAyODN8LTE2MTY4NDE4NTE=>
> .
> NAML
> <http://python.6.x6.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>
--
View this message in context: http://python.6.x6.nabble.com/Hover-Event-for-a-QGraphicsItem-tp5190283p5190340.html
Sent from the PyQt mailing list archive at Nabble.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20160508/4892e14c/attachment-0001.html>
More information about the PyQt
mailing list