Cannot save the state of Qt drawing - python

Maybe it is insufficient knowledge of Qt or of Python, of maybe even both, but I have a problem with Qt5 in Python.
I have a script that draws a line from a point where the mouse pointer is depressed to the point where it is released. That works fine.
Then when I want to draw a second line, I want to keep the first line on the QDialog as well, but because the way paintEvent works that is not possible straight away.
There for I've created a helper class (at first it was in the MyDialog class itself) to store all the points in a list and then use this class to redraw all the lines when paintEvent redraws the QDialog.
However, this is not working because for some reason all the points stored in the helper class get overridden by the last point. So if I draw ten lines, the helper class has 10 times the last (10th) point in its list.
Below you can see the code, can somebody shine a light on this? Thank!
import sys
from PyQt5.QtWidgets import QDialog, QApplication
from PyQt5.QtGui import QPainter, QPicture
from demoDrawLine import *
class ContextTest:
test = []
class MyForm(QDialog):
picture = []
def __init__(self):
super().__init__()
self.drawing = []
self.ui = Ui_Dialog()
self.ui.setupUi(self)
self.pos1 = [0,0]
self.pos2 = [0,0]
self.show()
def paintEvent(self, event):
super().paintEvent(event)
qp = QPainter()
qp.begin(self)
qp.drawLine(self.pos1[0], self.pos1[1], self.pos2[0], self.pos2[1])
qp.end()
def mousePressEvent(self, event):
if event.buttons() & QtCore.Qt.LeftButton:
self.pos1[0], self.pos1[1] = event.pos().x(), event.pos().y()
def mouseReleaseEvent(self, event):
self.pos2[0], self.pos2[1] = event.pos().x(), event.pos().y()
ContextTest.test.append((self.pos1, self.pos2))
self.update()
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyForm()
w.show()
sys.exit(app.exec_())
Here some results I copied from the debugger:
1st line drawn: ContextTest.test : [([150, 335], [452, 618])]
2nd line drawn: ContextTest.test : [([311, 695], [340, 666]), ([311, 695], [340, 666])]
3rd line drawn: ContextTest.test : [([1444, 249], [1043, 712]), ([1444, 249], [1043, 712]), ([1444, 249], [1043, 712])]
etc...

You are saving the points in test but you are not using it to paint, as you realized paintEvent has no notion of the past so you will have to save those points but better than saving points would be to keep instructions that know how to paint, for example it could add other figures without needing to write a lot of code in it.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Instruction:
def paint(self, painter):
raise NotImplementedError()
class LineInstruction(Instruction):
def __init__(self, line):
self._line = line
def paint(self, painter):
painter.drawLine(self._line)
class ContextTest:
instructions = []
class MyForm(QtWidgets.QDialog):
def __init__(self):
super().__init__()
self.drawing = []
self.show()
def paintEvent(self, event):
super().paintEvent(event)
qp = QtGui.QPainter(self)
for instruction in ContextTest.instructions:
instruction.paint(qp)
def mousePressEvent(self, event):
if event.buttons() & QtCore.Qt.LeftButton:
self.start = event.pos()
def mouseReleaseEvent(self, event):
l = QtCore.QLine(self.start, event.pos())
instruction = LineInstruction(l)
ContextTest.instructions.append(instruction)
self.update()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MyForm()
w.show()
sys.exit(app.exec_())

Related

How to make my title less Window drag-able in PyQt5?

I want to build a window which has no title bar, so i do. But it is not any more draggable. You cannot make my window move from here to there.
I know it is because of me, removing the title bar, but how to fix it?
This is my code:
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QWidget
import sys
def window():
app = QApplication(sys.argv)
win = QMainWindow()
win.setGeometry(300, 300, 300, 300)
win.setWindowTitle("Test")
win.setWindowFlags(QtCore.Qt.FramelessWindowHint)
label = QLabel(win)
label.setText("Hello world")
win.show()
sys.exit(app.exec_())
window()
Any help will be appreciated. Please help me with this...
You need to reimplement the mousePress and mouseMove methods of the widget (mouseRelease is technically not mandatory, but is actually required for consistency, as the release event has to be correctly intercepted by Qt to avoid any confusion). The former will get the current cursor position relative to the geometry (self.offset), while the latter will compute the new "window" position by adding the new position to the current one and subtracting the offset.
I would also suggest you to use a QWidget instead of a QMainWindow. While QMainWindow implementation is very similar to that of QWidgets, subclassing a QMainWindow for your purpose might be a bit harder, as it's widget more complex than it seems.
If you only need a QMainWindow to get a status bar, just add a new one to the widget layout; if you also need a menubar, add it to the widget's layout using setMenuBar.
class FramelessWidget(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Test")
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.label = QLabel("Hello world", self)
self.offset = None
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.offset = event.pos()
else:
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
if self.offset is not None and event.buttons() == QtCore.Qt.LeftButton:
self.move(self.pos() + event.pos() - self.offset)
else:
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
self.offset = None
super().mouseReleaseEvent(event)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = FramelessWidget()
win.setGeometry(300, 300, 300, 300)
win.show()
sys.exit(app.exec_())

QPropertyAnimation not working with Window Opacity

I'm setting up a new desktop widget to make my life easier at work and using QPropertyAnimation to make it pretty. Fading the app in and out doesn't seem to want to work and in typical coder fashion, it's brought my progress to a standstill.
I'm implementing QPropertyAnimation in a personalised class to make my life easier, but since it's not intially worked I've taken it back to the class code and it's still being pretty stubborn. So far I've tried.
class widget(QWidget):
def init(self):
self.setSize(QSize(300, 300))
self.setWindowOpacity(1)
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_TranslucentBackground)
def paintEvent(self, event):
s = self.size()
qp = QPainter()
qp.begin(self)
qp.setRenderHint(QPainter.Antialiasing, True)
qp.setBrush(QColor().fromRgb(2,106,194))
qp.setPen(QColor().fromRgb(2,106,194))
qp.drawRoundRect(QRect(0,0, 300, 300), 16, 8)
qp.end()
def show(self):
self.superShow()
a = QPropertyAnimation(self, "windowOpacity")
a.setDuration(500)
a.setStartValue(1)
a.setEndValue(0)
a.start()
def hide(self):
a = QPropertyAnimation(self, "windowOpacity")
a.setDuration(500)
a.setStartValue(0)
a.setEndValue(1)
a.finished.connect(self.superHide)
a.start()
def superShow(self):
super(widget, self).show()
def superHide(self):
super(widget, self).hide()
No error messages at all it just hides and shows after the animation duration is over. No idea where to look or what to do to get it working. I've only been coding for like 3 months or so.
Your code has many errors, for example:
I don't see where you call init().
Animations are local variables that will be removed when the show and hide methods are finished, which is almost instantaneous.
etc.
Instead of changing the opacity directly I will use QGraphicsOpacityEffect, instead of using the show and close method, I will use the showEvent, hideEvent and closeEvent methods.
import sys
from PySide2.QtCore import QEasingCurve, QEventLoop, QPropertyAnimation, QRect, QSize, Qt
from PySide2.QtGui import QColor, QPainter
from PySide2.QtWidgets import QAction, QApplication, QGraphicsOpacityEffect, QWidget
class Widget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.resize(QSize(300, 300))
# self.setWindowOpacity(1)
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.setContextMenuPolicy(Qt.ActionsContextMenu)
quit_action = QAction(self.tr("E&xit"), self)
quit_action.setShortcut(self.tr("Ctrl+Q"))
quit_action.triggered.connect(self.close)
self.addAction(quit_action)
effect = QGraphicsOpacityEffect(self, opacity=1.0)
self.setGraphicsEffect(effect)
self._animation = QPropertyAnimation(
self,
propertyName=b"opacity",
targetObject=effect,
duration=500,
startValue=0.0,
endValue=1.0,
)
def paintEvent(self, event):
qp = QPainter(self)
qp.setRenderHint(QPainter.Antialiasing, True)
qp.setBrush(QColor().fromRgb(2, 106, 194))
qp.setPen(QColor().fromRgb(2, 106, 194))
qp.drawRoundedRect(QRect(0, 0, 300, 300), 16, 8)
def fade_in(self):
self._animation.setDirection(QPropertyAnimation.Forward)
self._animation.start()
def fade_out(self):
loop = QEventLoop()
self._animation.finished.connect(loop.quit)
self._animation.setDirection(QPropertyAnimation.Backward)
self._animation.start()
loop.exec_()
def showEvent(self, event):
super().showEvent(event)
self.fade_in()
def closeEvent(self, event):
# fade out
self.fade_out()
super().closeEvent(event)
def hideEvent(self, event):
# fade out
self.fade_out()
super().hideEvent(event)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())

Move QLabel in absolute position with mouse move

I want to move the QLabel with the mouse movement (not like Drag&drop, 'object' disappears while moving). Clicked - moved - released. I did it to some extent, but I ran into a problem. QLabel shrinks as I move it or even disappears (like shrinks to 0 width). How to fix it or what more correct approach to do it?
(self.label_pos is needed to keep the mouse position relative inside self.label)
Or its just monitor's refresh rate issue? But in photoshop's gradient editor, that little color stop isn't shrikns. It's choppy because of refresh rate, but always the same size.
This is what I want to see, recorded using a screen capture program. The same thing I see in Photoshop
This is what I see, recorded on my phone. The quality is poor, but the difference is clearly visible anyway.
This Photoshop is also captured on my phone, here the “object” remains the same size, as in the example made using screen capture
Here is code from eyllanesc's answer, 'object' still shrinks :(
self.label = QLabel(self)
self.label.move(100, 100)
self.label.mousePressEvent = self.mouse_on
self.label.mouseReleaseEvent = self.mouse_off
def mouse_on(self, event):
self.bool = True
self.label_pos = event.pos()
def mouse_off(self, event):
self.bool = False
def mouseMoveEvent(self, event):
if self.bool:
self.label.move(event.x()-self.label_pos.x(), event.y()-self.label_pos.y())
Instead of using a QLabel I recommend using QGraphicsRectItem with a QGraphicsView since it is specialized in this type of tasks:
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.setScene(QtWidgets.QGraphicsScene(self))
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
brush = QtWidgets.QApplication.palette().brush(QtGui.QPalette.Window)
self.setBackgroundBrush(brush)
rect_item = self.scene().addRect(
QtCore.QRectF(QtCore.QPointF(), QtCore.QSizeF(40, 80))
)
rect_item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
rect_item.setBrush(QtGui.QBrush(QtGui.QColor("red")))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.setFixedSize(640, 480)
w.show()
sys.exit(app.exec_())
If you want to just scroll horizontally then overwrite the itemChange method of QGraphicsItem:
from PyQt5 import QtCore, QtGui, QtWidgets
class HorizontalItem(QtWidgets.QGraphicsRectItem):
def __init__(self, rect, parent=None):
super(HorizontalItem, self).__init__(rect, parent)
self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges, True)
def itemChange(self, change, value):
if (
change == QtWidgets.QGraphicsItem.ItemPositionChange
and self.scene()
):
return QtCore.QPointF(value.x(), self.pos().y())
return super(HorizontalItem, self).itemChange(change, value)
class Widget(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.setScene(QtWidgets.QGraphicsScene(self))
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
brush = QtWidgets.QApplication.palette().brush(QtGui.QPalette.Window)
self.setBackgroundBrush(brush)
rect_item = HorizontalItem(
QtCore.QRectF(QtCore.QPointF(), QtCore.QSizeF(40, 80))
)
rect_item.setBrush(QtGui.QBrush(QtGui.QColor("red")))
self.scene().addItem(rect_item)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.setFixedSize(640, 480)
w.show()
sys.exit(app.exec_())
In the following code there is an example similar to what you want:
from PyQt5 import QtCore, QtGui, QtWidgets
class HorizontalItem(QtWidgets.QGraphicsRectItem):
def __init__(self, rect, parent=None):
super(HorizontalItem, self).__init__(rect, parent)
self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges, True)
def itemChange(self, change, value):
if (
change == QtWidgets.QGraphicsItem.ItemPositionChange
and self.scene()
):
return QtCore.QPointF(value.x(), self.pos().y())
return super(HorizontalItem, self).itemChange(change, value)
class Widget(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.setScene(QtWidgets.QGraphicsScene(self))
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
brush = QtWidgets.QApplication.palette().brush(QtGui.QPalette.Window)
self.setBackgroundBrush(brush)
self.setFixedSize(640, 480)
size = self.mapToScene(self.viewport().rect()).boundingRect().size()
r = QtCore.QRectF(QtCore.QPointF(), size)
self.setSceneRect(r)
rect = QtCore.QRectF(
QtCore.QPointF(), QtCore.QSizeF(0.8 * r.width(), 80)
)
rect.moveCenter(r.center())
rect_item = self.scene().addRect(rect)
rect_item.setBrush(QtGui.QBrush(QtGui.QColor("salmon")))
item = HorizontalItem(
QtCore.QRectF(
rect.bottomLeft() + QtCore.QPointF(0, 20), QtCore.QSizeF(20, 40)
)
)
item.setBrush(QtGui.QBrush(QtGui.QColor("red")))
self.scene().addItem(item)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())

Mouse position in mouseMoveEvent and mousePressEvent are different: QGraphicsObject

Mouse position in mouseMoveEvent and mousePressEvent are different in the following example. This is happening due to the added scaling. Without scaling the positions are same.
Do I have to update the boundingRect according to the changed scaling? How?
#!/usr/bin/env python
from PyQt5.QtCore import (QRectF)
from PyQt5.QtGui import (QPainter, QPixmap)
from PyQt5.QtWidgets import (QMainWindow, QApplication, QGraphicsObject, QGraphicsView, QGraphicsScene)
class TicTacToe(QGraphicsObject):
def __init__(self, helper):
super(TicTacToe, self).__init__()
self.mypixmap = QPixmap("exit1.png")
def paint(self, painter, option, widget):
painter.setOpacity(1)
painter.drawPixmap(0,0, 512, 512, self.mypixmap)
painter.drawLine(2,2,20,20)
def boundingRect(self):
return QRectF(0,0,512, 512)
def keyPressEvent(self, event):
print "aaaaaaaaaa"
def mouseMoveEvent(self, event):
print "ccccccccccc ", event.pos()
def mousePressEvent(self, event):
print "bbbbbbbbbbbb", event.pos()
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
self.scene = QGraphicsScene(self)
self.tic_tac_toe = TicTacToe(self)
self.myScale = 2
self.tic_tac_toe.setScale(self.myScale)
self.setScene(self.scene)
self.scene.addItem(self.tic_tac_toe)
self.setMouseTracking(True)
def keyPressEvent(self, event):
self.tic_tac_toe.keyPressEvent(event)
def mouseMoveEvent(self, event):
print "mouse"
self.tic_tac_toe.mouseMoveEvent(event)
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.y = MyGraphicsView()
self.setCentralWidget(self.y)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = Example()
w.show()
sys.exit(app.exec_())
The problem is caused because you are sending the QGraphicsView events to a QGraphicsObject. In the case of QGraphicsView the event is of the QMouseEvent type but in the case of QGraphicsObject it is of the QGraphicsSceneMouseEvent type. In conclusion, you should not pass the QGraphicsView events to the QGraphicsObject since they refer to different events with different information.
The mousePressEvent event is enabled by default but in the case of the mouseMoveEvent event it can not be handled by QGraphicsObject, instead you must use hoverMoveEvent but these will only work inside the boundingRect of the QGraphicsObject.
#!/usr/bin/env python
from PyQt5.QtCore import (QRectF)
from PyQt5.QtGui import (QPainter, QPixmap)
from PyQt5.QtWidgets import (QMainWindow, QApplication, QGraphicsObject, QGraphicsView, QGraphicsScene)
class TicTacToe(QGraphicsObject):
def __init__(self, helper):
super(TicTacToe, self).__init__()
self.mypixmap = QPixmap("exit1.png")
self.setAcceptHoverEvents(True)
def paint(self, painter, option, widget):
painter.setOpacity(1)
painter.drawPixmap(0,0, 512, 512, self.mypixmap)
painter.drawLine(2,2,20,20)
def boundingRect(self):
return QRectF(0,0,512, 512)
def hoverMoveEvent(self, event):
print("ccccccccccc ", event.pos())
def mousePressEvent(self, event):
print("bbbbbbbbbbbb", event.pos())
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
self.scene = QGraphicsScene(self)
self.tic_tac_toe = TicTacToe(self)
self.myScale = 2
self.tic_tac_toe.setScale(self.myScale)
self.setScene(self.scene)
self.scene.addItem(self.tic_tac_toe)
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.y = MyGraphicsView()
self.setCentralWidget(self.y)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = Example()
w.show()
sys.exit(app.exec_())
On the other hand, these points do not coincide with the position in the scene since those coordinates are relative to the item.
For you to understand better we could use the following analogy, let's say you are recording a scene with a camera, the camera's screen is like the QGraphicsView, the scene is the QGraphicsScene and the actors are the QGraphicsItems and QGraphicsObjects. Each of these elements has a different coordinate system.
In the case of QGraphicsView your QMouseEvent returns coordinates in units of pixels, if you want to convert it to coordinates of the scene you must use mapToScene().
In the case of the QGraphicsItem/QGraphicsObject have different coordinates to those of the scene, those are not affected by the transformations such as scale, rotation, etc. That is what is printing in the previous example. If you want to convert it to units of the scene you must use mapToScene().
In the following example I show all the impressions in units of the scene.
#!/usr/bin/env python
from PyQt5.QtCore import (QRectF)
from PyQt5.QtGui import (QPainter, QPixmap)
from PyQt5.QtWidgets import (QMainWindow, QApplication, QGraphicsObject, QGraphicsView, QGraphicsScene)
class TicTacToe(QGraphicsObject):
def __init__(self, helper):
super(TicTacToe, self).__init__()
self.mypixmap = QPixmap("exit1.png")
self.setAcceptHoverEvents(True)
def paint(self, painter, option, widget):
painter.setOpacity(1)
painter.drawPixmap(0,0, 512, 512, self.mypixmap)
painter.drawLine(2,2,20,20)
def boundingRect(self):
return QRectF(0,0,512, 512)
def hoverMoveEvent(self, event):
#print("hoverMoveEvent ", event.pos())
print("hoverMoveEvent", self.mapToScene(event.pos()))
def mousePressEvent(self, event):
#print("mousePressEvent", event.pos())
print("mousePressEvent", self.mapToScene(event.pos()))
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
self.scene = QGraphicsScene(self)
self.setMouseTracking(True)
self.tic_tac_toe = TicTacToe(self)
self.myScale = 2
self.tic_tac_toe.setScale(self.myScale)
self.setScene(self.scene)
self.scene.addItem(self.tic_tac_toe)
def mouseMoveEvent(self, event):
print("mouseMoveEvent", self.mapToScene(event.pos()))
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.y = MyGraphicsView()
self.setCentralWidget(self.y)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = Example()
w.show()
sys.exit(app.exec_())
If you want more information check the following links:
http://doc.qt.io/qt-5/graphicsview.html
http://blog.qt.io/blog/2017/01/19/should-you-be-using-qgraphicsview/

Drawing a line consisting of multiple points using PyQt

I want to draw a line consisting of multiple points via mouse click in a Python script using PyQt. I need all coordinates of the ponts and I want to be able to delete the line. Here's my script doing all the work, except for the graphical line drawing itself, it just prints what it does:
#!/usr/bin/python3
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class endomess(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.draw = False
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
if self.draw == False:
print('Starting to draw at', str(event.pos()))
self.draw = True
self.linePoints = []
elif self.draw == True:
print('Appending', str(event.pos()))
self.linePoints.append(event.pos())
elif event.button() == Qt.RightButton:
if self.draw == True:
print('Finished drawing. List of all points:', str(self.linePoints))
self.draw = False
def main(argv):
app = QApplication(argv, True)
wnd = endomess()
wnd.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main(sys.argv)
So, here's my problem: how do I actually draw that line that can be defined via the above script? I already had a look at scribble.py and some Qt paint docs, but I don't get it. Probably, this is not a problem for someone more experienced with Qt?
Thanks in advance for all help!
You should probably use the graphics view framework for drawing the lines, rather than attempting to paint them directly.
Here's a basic demo to get you started:
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.view = View(self)
self.button = QtGui.QPushButton('Clear View', self)
self.button.clicked.connect(self.handleClearView)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.view)
layout.addWidget(self.button)
def handleClearView(self):
self.view.scene().clear()
class View(QtGui.QGraphicsView):
def __init__(self, parent):
QtGui.QGraphicsView.__init__(self, parent)
self.setScene(QtGui.QGraphicsScene(self))
self.setSceneRect(QtCore.QRectF(self.viewport().rect()))
def mousePressEvent(self, event):
self._start = event.pos()
def mouseReleaseEvent(self, event):
start = QtCore.QPointF(self.mapToScene(self._start))
end = QtCore.QPointF(self.mapToScene(event.pos()))
self.scene().addItem(
QtGui.QGraphicsLineItem(QtCore.QLineF(start, end)))
for point in (start, end):
text = self.scene().addSimpleText(
'(%d, %d)' % (point.x(), point.y()))
text.setBrush(QtCore.Qt.red)
text.setPos(point)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.resize(640, 480)
window.show()
sys.exit(app.exec_())

Categories