def mousePressEvent(self, event): """ React on a mouse event - move cursor to position of the event. """ if event.button() == Qt.RightButton: event = QMouseEvent(QEvent.MouseButtonPress, event.pos(), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier) QPlainTextEdit.mousePressEvent(self, event)
def mouseMoveEvent(self, event): # for less calls to widgetsAt() widgetsUnderCusor = self.widgetsAt(event.x(), event.y()) mouseEvent = MouseEvent.fromQtEvent(event) if widgetsUnderCusor is not None: for widget in widgetsUnderCusor: mouseEvent.x -= widget.x() # adjust coordinates to widget top left mouseEvent.y -= widget.y() if not widget in self._widgetsPreviouslyUnderCursor: widget._mouseEnterEvent(mouseEvent) widget._mouseMoveEvent(mouseEvent) mouseEvent.x += widget.x() # reset coordinates mouseEvent.y += widget.y() for widget in self._widgetsPreviouslyUnderCursor: if not widget in widgetsUnderCusor: mouseEvent.x -= widget.x() # adjust coordinates to widget top left mouseEvent.y -= widget.y() widget._mouseExitEvent(mouseEvent) mouseEvent.x += widget.x() # reset coordinates mouseEvent.y += widget.y() # get ready for the next mouse move event self._widgetsPreviouslyUnderCursor = self.widgetsAt(event.x(), event.y()) self._previousMouseMoveEvent = QMouseEvent(QEvent.HoverMove,QPoint(event.pos()),QPoint(event.globalPos()), event.button(),event.buttons(),event.modifiers()) return QWidget.mouseMoveEvent(self, event)
def leaveEvent(self, event): for widget in self.widgetsAt(self._previousMouseMoveEvent.x(), self._previousMouseMoveEvent.y()): widget._mouseExitEvent(MouseEvent.fromQtEvent(self._previousMouseMoveEvent)) self._previousMouseMoveEvent = QMouseEvent(QEvent.HoverMove,QPoint(-1,-1), Qt.NoButton,Qt.NoButton,Qt.NoModifier) self._widgetsPreviouslyUnderCursor = []
def __init__(self): QWidget.__init__(self) self._properties = [] self._propertySets = [] self._view = None # to avoid errors when setting properties self.width = IntProperty(self,self.width()) self.height = IntProperty(self,self.height()) self.setMouseTracking(True) # to receive certain events self._previousMouseMoveEvent = QMouseEvent(QEvent.HoverMove,QPoint(-1,-1), Qt.NoButton,Qt.NoButton,Qt.NoModifier) self._widgetsPreviouslyUnderCursor = []
class OxideView(QWidget): _widgets = () def __init__(self): QWidget.__init__(self) self._properties = [] self._propertySets = [] self._view = None # to avoid errors when setting properties self.width = IntProperty(self,self.width()) self.height = IntProperty(self,self.height()) self.setMouseTracking(True) # to receive certain events self._previousMouseMoveEvent = QMouseEvent(QEvent.HoverMove,QPoint(-1,-1), Qt.NoButton,Qt.NoButton,Qt.NoModifier) self._widgetsPreviouslyUnderCursor = [] def __setattr__(self, name, value): if not hasattr(self, name): # if the attribute is being newly created return super(QWidget, self).__setattr__(name,value) # otherwise attr = super(QWidget, self).__getattribute__(name) # get the attribute if isinstance(attr, BaseProperty): # if it is an oxide property return attr.setTo(value) # set the property elif isinstance(attr, CompoundProperty): return attr.setTo(value) return super(QWidget, self).__setattr__(name,value) # otherwise use parent implementation def widgetsFrontToBack(self): if self._widgets: # widgets list is not empty tmplist = list(self._widgets) tmplist.reverse() return tmplist # return the reversed list def paintEvent(self, event): painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) for widget in self._widgets: painter.translate(widget.x(),widget.y()) # move the painter to the widget's coordinates painter.setClipRect(0,0,widget.width(),widget.height()) # restrict the painting area widget._paint(painter) # paint the widget painter.translate(-widget.x(),-widget.y()) # get the painter ready for the next widget painter.setClipRect(self.rect()) # to be painted painter.end() def addWidget(self,widget): if not isinstance(widget, Widget): # type safety raise TypeError, TypeErrorText('widget', "OxideView.addWidget", 'Widget') self._widgets += (widget,) # add to the internal list of widgets widget._view = self # allows for updating when properties are changed def widgetsAt(self,x,y): # gets the widgets at the coordinates (x,y) widgetsAtPoint = [] if self.widgetsFrontToBack() is None: return None # if the view has no widgets for widget in self.widgetsFrontToBack(): # get the widgets in the front first if QRect(widget.x(),widget.y(),widget.width(),widget.height()).contains(x,y): widgetsAtPoint.append(widget) # if the cursor was within the bounds of this widget return widgetsAtPoint def mousePressEvent(self, qtevent): event = MouseEvent.fromQtEvent(qtevent) if self.widgetsAt(event.x,event.y) is not None: for widget in self.widgetsAt(event.x,event.y): event.x -= widget.x() event.y -= widget.y() if not Event.shouldPropagate(widget._mousePressEvent(event)): return False event.x += widget.x() event.y += widget.y() return QWidget.mousePressEvent(self, qtevent) def mouseMoveEvent(self, event): # for less calls to widgetsAt() widgetsUnderCusor = self.widgetsAt(event.x(), event.y()) mouseEvent = MouseEvent.fromQtEvent(event) if widgetsUnderCusor is not None: for widget in widgetsUnderCusor: mouseEvent.x -= widget.x() # adjust coordinates to widget top left mouseEvent.y -= widget.y() if not widget in self._widgetsPreviouslyUnderCursor: widget._mouseEnterEvent(mouseEvent) widget._mouseMoveEvent(mouseEvent) mouseEvent.x += widget.x() # reset coordinates mouseEvent.y += widget.y() for widget in self._widgetsPreviouslyUnderCursor: if not widget in widgetsUnderCusor: mouseEvent.x -= widget.x() # adjust coordinates to widget top left mouseEvent.y -= widget.y() widget._mouseExitEvent(mouseEvent) mouseEvent.x += widget.x() # reset coordinates mouseEvent.y += widget.y() # get ready for the next mouse move event self._widgetsPreviouslyUnderCursor = self.widgetsAt(event.x(), event.y()) self._previousMouseMoveEvent = QMouseEvent(QEvent.HoverMove,QPoint(event.pos()),QPoint(event.globalPos()), event.button(),event.buttons(),event.modifiers()) return QWidget.mouseMoveEvent(self, event) def leaveEvent(self, event): for widget in self.widgetsAt(self._previousMouseMoveEvent.x(), self._previousMouseMoveEvent.y()): widget._mouseExitEvent(MouseEvent.fromQtEvent(self._previousMouseMoveEvent)) self._previousMouseMoveEvent = QMouseEvent(QEvent.HoverMove,QPoint(-1,-1), Qt.NoButton,Qt.NoButton,Qt.NoModifier) self._widgetsPreviouslyUnderCursor = [] def resizeEvent(self, event): self.width = event.size().width() self.height = event.size().height()