I looked around and i could not find anything. So here I am. i am making a very simple drawing sofware in python using pyqt. im starting with a rectangle draw tool. For some reason(maybe due to lack understanding), I cannot for the life of me to get this to work. It is a blank screen that when you click and drag should use the rectangle tool to create the shape. there is a button on there but it is not programmed to do anything yet. When you click in the area it reads the mouse click but no movement or release events. I added a debugger so you can see. now if you click the outer edge of the program(like in the border parts) it will read all events you can even start to draw your rectangle. you just have to start at the edges. This is a fresh install of Python and a new virtual environment that only holds what needs to be installed. Any insight will be awesome! Thanks in advance!
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QGraphicsScene, QGraphicsView, QVBoxLayout, QWidget, QMessageBox, QFileDialog, QGraphicsRectItem
from PyQt5.QtGui import QPixmap, QImage, QPen, QColor
from PyQt5.QtCore import Qt, QPointF
class Test(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.image_path = None
self.start_point = None
self.rect_item = None
self.confirmed_rects = []
def initUI(self):
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.layout = QVBoxLayout(self.central_widget)
self.fetch_random_button = QPushButton("Test")
self.scene = QGraphicsScene(self)
self.view = QGraphicsView(self.scene, self)
self.layout.addWidget(self.view)
self.setGeometry(100, 100, 800, 600)
self.setWindowTitle('Test')
def mousePressEvent(self, event):
scene_pos = self.view.mapToScene(event.pos())
self.start_point = scene_pos
print(f"mousePressEvent: scene_pos = {scene_pos}")
def mouseMoveEvent(self, event):
if self.start_point:
scene_pos = self.view.mapToScene(event.pos())
top_left, width, height = self.create_rectangle(self.start_point, scene_pos)
print(f"mouseMoveEvent: scene_pos = {scene_pos}, top_left = {top_left}, width = {width}, height = {height}")
if self.rect_item:
self.scene.removeItem(self.rect_item)
pen = QPen(QColor(0, 0, 255))
pen.setWidth(2)
self.rect_item = QGraphicsRectItem(top_left.x(), top_left.y(), width, height)
self.rect_item.setPen(pen)
self.scene.addItem(self.rect_item)
def mouseReleaseEvent(self, event):
print("mouseReleaseEvent")
self.start_point = None
self.rect_item = None
def create_rectangle(self, start_point, end_point):
x = min(start_point.x(), end_point.x())
y = min(start_point.y(), end_point.y())
width = abs(start_point.x() - end_point.x())
height = abs(start_point.y() - end_point.y())
print(f"create_rectangle: start_point = {start_point}, end_point = {end_point}, x = {x}, y = {y}, width = {width}, height = {height}")
return QPointF(x, y), width, height
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Test()
window.show()
sys.exit(app.exec_())
I looked around and i could not find anything. So here I am. i am making a very simple drawing sofware in python using pyqt. im starting with a rectangle draw tool. For some reason(maybe due to lack understanding), I cannot for the life of me to get this to work. It is a blank screen that when you click and drag should use the rectangle tool to create the shape. there is a button on there but it is not programmed to do anything yet. When you click in the area it reads the mouse click but no movement or release events. I added a debugger so you can see. now if you click the outer edge of the program(like in the border parts) it will read all events you can even start to draw your rectangle. you just have to start at the edges. This is a fresh install of Python and a new virtual environment that only holds what needs to be installed. Any insight will be awesome! Thanks in advance!
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QGraphicsScene, QGraphicsView, QVBoxLayout, QWidget, QMessageBox, QFileDialog, QGraphicsRectItem
from PyQt5.QtGui import QPixmap, QImage, QPen, QColor
from PyQt5.QtCore import Qt, QPointF
class Test(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.image_path = None
self.start_point = None
self.rect_item = None
self.confirmed_rects = []
def initUI(self):
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.layout = QVBoxLayout(self.central_widget)
self.fetch_random_button = QPushButton("Test")
self.scene = QGraphicsScene(self)
self.view = QGraphicsView(self.scene, self)
self.layout.addWidget(self.view)
self.setGeometry(100, 100, 800, 600)
self.setWindowTitle('Test')
def mousePressEvent(self, event):
scene_pos = self.view.mapToScene(event.pos())
self.start_point = scene_pos
print(f"mousePressEvent: scene_pos = {scene_pos}")
def mouseMoveEvent(self, event):
if self.start_point:
scene_pos = self.view.mapToScene(event.pos())
top_left, width, height = self.create_rectangle(self.start_point, scene_pos)
print(f"mouseMoveEvent: scene_pos = {scene_pos}, top_left = {top_left}, width = {width}, height = {height}")
if self.rect_item:
self.scene.removeItem(self.rect_item)
pen = QPen(QColor(0, 0, 255))
pen.setWidth(2)
self.rect_item = QGraphicsRectItem(top_left.x(), top_left.y(), width, height)
self.rect_item.setPen(pen)
self.scene.addItem(self.rect_item)
def mouseReleaseEvent(self, event):
print("mouseReleaseEvent")
self.start_point = None
self.rect_item = None
def create_rectangle(self, start_point, end_point):
x = min(start_point.x(), end_point.x())
y = min(start_point.y(), end_point.y())
width = abs(start_point.x() - end_point.x())
height = abs(start_point.y() - end_point.y())
print(f"create_rectangle: start_point = {start_point}, end_point = {end_point}, x = {x}, y = {y}, width = {width}, height = {height}")
return QPointF(x, y), width, height
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Test()
window.show()
sys.exit(app.exec_())
Share
Improve this question
asked Mar 12 at 18:18
Damion OwensDamion Owens
231 silver badge7 bronze badges
1 Answer
Reset to default 0The issue is that when you click within the QGraphicsView, the mouse events are intercepted by it and not passed to the QMainWindow. You need to create your own QGraphicsView which will handle those events as you want.
Here is a modification of your program which properly handles the mouse events:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QGraphicsScene, QGraphicsView, QVBoxLayout, QWidget, QMessageBox, QFileDialog, QGraphicsRectItem
from PyQt5.QtGui import QPixmap, QImage, QPen, QColor
from PyQt5.QtCore import Qt, QPointF
class GraphicsView(QGraphicsView):
def __init__(self, scene, parent=None):
super().__init__(scene, parent)
self.image_path = None
self.start_point = None
self.rect_item = None
self.confirmed_rects = []
def mousePressEvent(self, event):
scene_pos = self.mapToScene(event.pos())
self.start_point = scene_pos
print(f"mousePressEvent: scene_pos = {scene_pos}")
def mouseMoveEvent(self, event):
if self.start_point:
scene_pos = self.mapToScene(event.pos())
top_left, width, height = self.create_rectangle(self.start_point, scene_pos)
print(f"mouseMoveEvent: scene_pos = {scene_pos}, top_left = {top_left}, width = {width}, height = {height}")
if self.rect_item:
self.scene().removeItem(self.rect_item)
pen = QPen(QColor(0, 0, 255))
pen.setWidth(2)
self.rect_item = QGraphicsRectItem(top_left.x(), top_left.y(), width, height)
self.rect_item.setPen(pen)
self.scene().addItem(self.rect_item)
def mouseReleaseEvent(self, event):
print("mouseReleaseEvent")
self.start_point = None
self.rect_item = None
def create_rectangle(self, start_point, end_point):
x = min(start_point.x(), end_point.x())
y = min(start_point.y(), end_point.y())
width = abs(start_point.x() - end_point.x())
height = abs(start_point.y() - end_point.y())
print(f"create_rectangle: start_point = {start_point}, end_point = {end_point}, x = {x}, y = {y}, width = {width}, height = {height}")
return QPointF(x, y), width, height
class Test(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.image_path = None
self.start_point = None
self.rect_item = None
self.confirmed_rects = []
def initUI(self):
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.layout = QVBoxLayout(self.central_widget)
self.fetch_random_button = QPushButton("Test")
self.scene = QGraphicsScene(self)
self.view = GraphicsView(self.scene, self) # Use your own GraphicsView
self.layout.addWidget(self.view)
self.setGeometry(100, 100, 800, 600)
self.setWindowTitle('Test')
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Test()
window.show()
sys.exit(app.exec_())