[PyQt] How to select and test if a QGraphicsItem (or a QGraphicsPixmapItem) has been selected
sw33tz
nyavuz.nm20 at gmail.com
Tue Apr 26 15:19:26 BST 2016
This is the full code:
#!/usr/bin/python
*import *threading
*import *sys
*from *PyQt4 *import *QtGui, QtCore, uic
*global *host_list, host_cs, switch_cs, connectLine_cs
host_list = []
switch_list = []
hostItem_list = []
switchItem_list = []
lineItem_list = []
host_cs = 0
switch_cs = 0
connectLine_cs = 0
*class **host_Object*(QtGui.QGraphicsPixmapItem, QtGui.QWidget):
*def *__init__(self, parent=None):
super(host_Object, self).__init__(parent)
pixmap = QtGui.QPixmap("host.png")
self.host_pixItem = QtGui.QGraphicsPixmapItem(pixmap.scaled(30, 30,
QtCore.Qt.KeepAspectRatio))
self
.host_pixItem.setFlag(QtGui.QGraphicsPixmapItem.ItemIsSelectable)
self.host_pixItem.setFlag(QtGui.QGraphicsPixmapItem.ItemIsMovable)
*def **mousePressEvent*(self, event):
*if *self.host_pixItem.isSelected():
*print *'selected object'
*class **graphicsScene*(QtGui.QGraphicsScene, QtGui.QWidget):
*def *__init__(self, parent=None):
super(graphicsScene, self).__init__(parent)
self.i = 0
self.j = 0
self.setSceneRect(-180, -90, 360, 180)
self.pen = QtGui.QPen(QtCore.Qt.black, 3, QtCore.Qt.SolidLine)
self.under_mouse = 0
*def **mousePressEvent*(self, event):
*global *host_cs
*if *host_cs == 1:
self.host_item = host_Object()
*for *host *in *hostItem_list:
*if *host.isUnderMouse():
*print *'selected'
*elif *connectLine_cs == 1:
self.cursorStartPosition = event.scenePos()
self.start = QtCore.QPoint(self.cursorStartPosition.x(),self
.cursorStartPosition.y())
*def **mouseMoveEvent*(self, event):
*if *self.start:
self.cursorCurrentPosition = event.scenePos()
current = QtCore.QPointF(self.cursorCurrentPosition.x(),self
.cursorCurrentPosition.y())
self.draw_line(current)
*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):
*global *host_cs
*if *host_cs == 1:
self.addItem(self.host_item.host_pixItem)
self.host_item.host_pixItem.setPos(event.scenePos())
hostItem_list.append(self.host_item.host_pixItem)
self.i += 1
host_list.append('h' + str(self.i))
*elif *switch_cs == 1:
pixmap = QtGui.QPixmap("switch.png")
switch_pixItem = QtGui.QGraphicsPixmapItem(pixmap.scaled(30, 30,
QtCore.Qt.KeepAspectRatio))
self.addItem(switch_pixItem)
switch_pixItem.setPos(event.scenePos())
switchItem_list.append(switch_pixItem)
self.j += 1
switch_list.append('s' + str(self.j))
self.update()
*elif *connectLine_cs == 1:
lineItem_list.append(self.line)
*for *link *in *lineItem_list:
self.addItem(link)
*class **mininetGUI*(QtGui.QMainWindow, QtGui.QWidget):
*def *__init__(self):
super(mininetGUI, self).__init__()
self.ui = uic.loadUi('minipynet.ui')
self.ui.actionHost.triggered.connect(self.place_host)
self.ui.actionSwitch.triggered.connect(self.place_switch)
self.ui.actionConnectLine.triggered.connect(self.connect_line)
self.scene = graphicsScene()
self.ui.view.setScene(self.scene)
*def **place_host*(self):
*global *host_cs
*global *switch_cs
*global *connectLine_cs
host_cs = 1
switch_cs = 0
connectLine_cs = 0
*def **place_switch*(self):
*global *host_cs
*global *switch_cs
*global *connectLine_cs
switch_cs = 1
host_cs = 0
connectLine_cs = 0
*def **connect_line*(self):
*global *host_cs
*global *switch_cs
*global *connectLine_cs
switch_cs = 0
host_cs = 0
connectLine_cs = 1
#self.setMouseTracking(True)
*if *__name__ == '__main__':
app = QtGui.QApplication(sys.argv) # A new instance of QApplication
form = mininetGUI() # We set the form to be our mininetGUI
form.ui.show() # Show the form
app.exec_()
On Tue, Apr 26, 2016 at 5:29 PM, Nesibe Yavuz <nyavuz.nm20 at gmail.com> wrote:
> I want to implement your second suggestion :
>
> "2) If you want your host/switch/line tools et.c to also double as
> selection tools (e.g. click outside an item will create a new item,
> while click on an item will select it), then you need to check if
> there's an item under the cursor when the click happens, and if there
> is, select it, otherwise go on with your current logic. "
>
> And to do that I wrote this code:
>
> *if *host_cs == 1:
> self.host_item = host_Object()
> *for *host *in *hostItem_list:
> *if *host.isUnderMouse():
> *print *'under mouse'
>
> The problem here is that I can only select the first item I ever create
> and I have to keep on pressing the item (maybe about 4-5 times) until it
> can actually be selected. I tried using the isSelected() method to check if
> the item was selected and I still get the same result. I also tried to test
> for a collision when adding the items so the items aren't drawn over each
> other (for when trying to select an item the host_item keeps on being added
> to the scene):
>
> *if *host_cs == 1:
> self.host_item = host_Object()
> *for *host *in *hostItem_list:
> *if *self.host_item.host_pixItem.collidesWithItem(host):
>
> *print *'collision'
>
> Here the "*if *self.host_item.host_pixItem.collidesWithItem(host):"
> statement keeps giving "False" as the output even though when I try to add
> an item over another item the statement clearly should return "True".
>
>
> By the way I'm sorry for the late replies I try to take your suggestions
> in consideration and I try to implement them before replying back to you.
>
>
>
>
> On Mon, Apr 25, 2016 at 9:07 PM, Elvis Stansvik [via Python] <
> ml-node+s6n5189328h79 at n6.nabble.com> wrote:
>
>> 2016-04-25 19:27 GMT+02:00 sw33tz <[hidden email]
>> <http:///user/SendEmail.jtp?type=node&node=5189328&i=0>>:
>> > thank you for the reply. I am able to select the item when there is
>> only one
>> > item but I want the user to be able to add more than one item and also
>> > select any item that they added. With my code I can't do that because
>> with
>> > every press event it just keeps adding items. Is there a way I can make
>> this
>> > happen?
>>
>> For the first question, I think the default behavior is that you can
>> select multiple items by holding down Ctrl. If you want rubber band
>> selection, you can do it quite easily by setting the drag mode of the
>> QGraphicsView. If you want some more customized selection behavior, I
>> think you'll have to manually handle the mouse/keyboard events and
>> call setSelected on the items you want to select.
>>
>> For the second question: It again depends on what behavior you want:
>>
>> 1) If you want to have a "select tool" which the user must choose
>> before he/she can select, then I guess you would implement it
>> similarly to how you've implemented the host/switch/line tools that
>> you've shown. You would have an elif for your select tool, where you
>> let QGraphicsScene (the base class) handle the event, this will
>> forward the event to the item (instead of it being swallowed by the
>> scene event handler like you did, and the item will select itself.
>>
>> 2) If you want your host/switch/line tools et.c to also double as
>> selection tools (e.g. click outside an item will create a new item,
>> while click on an item will select it), then you need to check if
>> there's an item under the cursor when the click happens, and if there
>> is, select it, otherwise go on with your current logic.
>>
>> This is all from memory, so better check the docs. But I hope it gets
>> you started.
>>
>> Googling also gives a lot of hits about selection handling with
>> QGraphicsScene/QGraphicsView.
>>
>> Elvis
>>
>> >
>> >
>> >
>> > --
>> > View this message in context:
>> http://python.6.x6.nabble.com/How-to-select-and-test-if-a-QGraphicsItem-or-a-QGraphicsPixmapItem-has-been-selected-tp5189232p5189325.html
>> > Sent from the PyQt mailing list archive at Nabble.com.
>> > _______________________________________________
>> > PyQt mailing list [hidden email]
>> <http:///user/SendEmail.jtp?type=node&node=5189328&i=1>
>> > https://www.riverbankcomputing.com/mailman/listinfo/pyqt
>> _______________________________________________
>> PyQt mailing list [hidden email]
>> <http:///user/SendEmail.jtp?type=node&node=5189328&i=2>
>> 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/How-to-select-and-test-if-a-QGraphicsItem-or-a-QGraphicsPixmapItem-has-been-selected-tp5189232p5189328.html
>> To unsubscribe from How to select and test if a QGraphicsItem (or a
>> QGraphicsPixmapItem) has been selected, click here
>> <http://python.6.x6.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=5189232&code=bnlhdnV6Lm5tMjBAZ21haWwuY29tfDUxODkyMzJ8LTE2MTY4NDE4NTE=>
>> .
>> 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/How-to-select-and-test-if-a-QGraphicsItem-or-a-QGraphicsPixmapItem-has-been-selected-tp5189232p5189415.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/20160426/66583145/attachment-0001.html>
More information about the PyQt
mailing list