PyQt5 - Drag and Drop in QDialog - python

I have a main pyqt5 application.
On click of a button i would like to call a QDialog and on submit of QDialog want to capture the result of QDialog in main application.
Below is a pyqt module which i like add it to QDialog, is this possible, and want to capture the result as well in main application ?
I don't know where to start.
import sys
from PyQt5.QtCore import QSize
from PyQt5 import QtWidgets, QtCore,QtGui
from PyQt5.QtGui import QColor, QDrag, QPainter, QPixmap
from PyQt5.QtWidgets import QApplication
from PyQt5 import QtCore, QtWidgets
from win32api import GetSystemMetrics
from PyQt5.QtGui import QImage, QPalette, QBrush
w=GetSystemMetrics(0)/1366
h=GetSystemMetrics(1)/768
class Button(QtWidgets.QPushButton):
def mouseMoveEvent(self, e):
if e.buttons() != QtCore.Qt.LeftButton:
return
# write the relative cursor position to mime data
mimeData = QtCore.QMimeData()
# simple string with 'x,y'
mimeData.setText('%d,%d' % (e.x(), e.y()))
pixmap = QtWidgets.QWidget.grab(self)
# below makes the pixmap half transparent
painter = QtGui.QPainter(pixmap)
painter.setCompositionMode(painter.CompositionMode_DestinationIn)
painter.fillRect(pixmap.rect(), QtGui.QColor(0, 0, 0, 127))
painter.end()
# make a QDrag
drag = QtGui.QDrag(self)
# put our MimeData
drag.setMimeData(mimeData)
# set its Pixmap
drag.setPixmap(pixmap)
# shift the Pixmap so that it coincides with the cursor position
drag.setHotSpot(e.pos())
# start the drag operation
# exec_ will return the accepted action from dropEvent
if drag.exec_(QtCore.Qt.CopyAction | QtCore.Qt.MoveAction) == QtCore.Qt.MoveAction:
print('moved')
else:
print('copied')
class Example(QtWidgets.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.setAcceptDrops(True)
button = Button('Draggable Text', self)
button.setStyleSheet("font-size: 15px;background-color: rgb(255,255,255); margin:5px; border:1px solid rgb(255, 255, 255); ")
button.move(100, 65)
self.buttons = [button]
self.setWindowTitle('Copy or Move')
self.setFixedSize(960, 515)
oImage = QImage(r"C:\Users\vaas\Desktop\background.jpg")
sImage = oImage.scaled(QSize(960*w/1,515*h/1)) # resize Image to widgets size
palette = QPalette()
palette.setBrush(QPalette.ColorRole(10), QBrush(sImage)) # 10 = Windowrole
self.setPalette(palette)
def dragEnterEvent(self, e):
e.accept()
def dropEvent(self, e):
# get the relative position from the mime data
mime = e.mimeData().text()
x, y = map(int, mime.split(','))
if e.keyboardModifiers() & QtCore.Qt.ShiftModifier:
# copy
# so create a new button
button = Button('Button', self)
# move it to the position adjusted with the cursor position at drag
button.move(e.pos()-QtCore.QPoint(x, y))
# show it
button.show()
# store it
self.buttons.append(button)
# set the drop action as Copy
e.setDropAction(QtCore.Qt.CopyAction)
else:
# move
# so move the dragged button (i.e. event.source())
print('mineĀ°',e.pos())
e.source().move(e.pos()-QtCore.QPoint(x, y))
# set the drop action as Move
e.setDropAction(QtCore.Qt.MoveAction)
# tell the QDrag we accepted it
e.accept()
def main():
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Start with http://doc.qt.io/qt-5/dnd.html
Play with the example below:
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import QSize
from PyQt5.QtGui import (QColor, QDrag, QPainter, QPixmap,
QImage, QPalette, QBrush)
from PyQt5.QtWidgets import QApplication, QHBoxLayout, QVBoxLayout
from win32api import GetSystemMetrics
w=GetSystemMetrics(0)/1366
h=GetSystemMetrics(1)/768
### +++++++++++++++++++++++++++++
class Window2(QtWidgets.QWidget):
def __init__(self):
super().__init__()
# To be able to receive media dropped on a widget, call setAcceptDrops(true)
# for the widget, and reimplement the dragEnterEvent() and
# dropEvent() event handler functions.
self.setAcceptDrops(True)
self.setGeometry(QtCore.QRect(20, 50, 180, 600))
self.lay = QVBoxLayout()
self.lay.addWidget(QtWidgets.QPushButton('Button1'))
self.lay.addWidget(QtWidgets.QPushButton('Button2'))
self.lay.addWidget(QtWidgets.QPushButton('Button3'))
palette = self.palette()
palette.setColor(QPalette.Window, QColor('blue'))
self.setPalette(palette)
self.setLayout(self.lay)
self.textLabel = ''
# The dragEnterEvent() function is typically used to inform Qt about the types
# of data that the widget accepts. You must reimplement this function
# if you want to receive either QDragMoveEvent or QDropEvent
# in your reimplementations of dragMoveEvent() and dropEvent().
def dragEnterEvent(self, e):
e.accept()
# The dropEvent() is used to unpack dropped data and
# handle it in way that is suitable for your application.
def dropEvent(self, e):
#self.textLabel = 'Drag and Drop. QLabel. e.mimeData().text() -> `{}`'.format(e.mimeData().text())
self.lay.addWidget(QtWidgets.QLabel('Drag and Drop. QLabel. e.mimeData().text() -> `{}`'\
.format(e.mimeData().text())))
e.accept()
class Button(QtWidgets.QPushButton):
def mouseMoveEvent(self, e):
if e.buttons() != QtCore.Qt.LeftButton:
return
# write the relative cursor position to mime data
mimeData = QtCore.QMimeData()
# simple string with 'x,y'
mimeData.setText('%d,%d' % (e.x(), e.y()))
pixmap = QtWidgets.QWidget.grab(self)
# below makes the pixmap half transparent
painter = QtGui.QPainter(pixmap)
painter.setCompositionMode(painter.CompositionMode_DestinationIn)
painter.fillRect(pixmap.rect(), QtGui.QColor(0, 0, 0, 127))
painter.end()
# make a QDrag
drag = QtGui.QDrag(self)
# put our MimeData
drag.setMimeData(mimeData)
# set its Pixmap
drag.setPixmap(pixmap)
# shift the Pixmap so that it coincides with the cursor position
drag.setHotSpot(e.pos())
# start the drag operation
# exec_ will return the accepted action from dropEvent
if drag.exec_(QtCore.Qt.CopyAction | QtCore.Qt.MoveAction) == QtCore.Qt.MoveAction:
print('moved')
else:
print('copied')
class Example(QtWidgets.QWidget):
def __init__(self):
super(Example, self).__init__()
self.w2 = Window2() # +++
self.w2.show() # +++
self.initUI()
def initUI(self):
self.setAcceptDrops(True)
button = Button('Draggable Text', self)
button.setStyleSheet("font-size: 15px;background-color: rgb(255,255,255); margin:5px; border:1px solid rgb(255, 255, 255); ")
button.move(100, 65)
self.buttons = [button]
self.setWindowTitle('Copy or Move')
self.setFixedSize(960, 515)
oImage = QImage(r"C:\Users\vaas\Desktop\background.jpg")
#oImage = QImage(r"logo.png")
sImage = oImage.scaled(QSize(960*w/1,515*h/1)) # resize Image to widgets size
palette = QPalette()
palette.setBrush(QPalette.ColorRole(10), QBrush(sImage)) # 10 = Windowrole
self.setPalette(palette)
def dragEnterEvent(self, e):
e.accept()
def dropEvent(self, e):
# get the relative position from the mime data
mime = e.mimeData().text()
x, y = map(int, mime.split(','))
if e.keyboardModifiers() & QtCore.Qt.ShiftModifier:
# copy
# so create a new button
button = Button('Button', self)
# move it to the position adjusted with the cursor position at drag
button.move(e.pos()-QtCore.QPoint(x, y))
# show it
button.show()
# store it
self.buttons.append(button)
# set the drop action as Copy
e.setDropAction(QtCore.Qt.CopyAction)
else:
# move
# so move the dragged button (i.e. event.source())
print('mineĀ°',e.pos())
e.source().move(e.pos()-QtCore.QPoint(x, y))
# set the drop action as Move
e.setDropAction(QtCore.Qt.MoveAction)
# tell the QDrag we accepted it
e.accept()
def main():
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Related

PyQT5 Add a label and icon in a rectangle

I've a list of rectangle make in this way:
import sys
from PyQt5.QtCore import Qt, QRect, QRectF
from PyQt5.QtGui import *
from PyQt5.QtWidgets import ( QGridLayout, QWidget, QApplication, QGraphicsScene,
QGraphicsView, QGraphicsProxyWidget, QGraphicsRectItem
)
class WidRect(QWidget):
def __init__(self, mIntMeasureId,mStrLabel=None):
super().__init__()
self.aIntMeasureId=mIntMeasureId
self.aStrLabel=mStrLabel
#self.setWidget(QLabel(mStrLabel))
def mousePressEvent(self, QMouseEvent):
if QMouseEvent.button() == Qt.LeftButton:
print("Left Button Clicked on measure "+ str(self.aIntMeasureId))
elif QMouseEvent.button() == Qt.RightButton:
#do what you want here
print("Right Button Clicked on measure "+ str(self.aIntMeasureId))
class MeasureGrid(QWidget):
#grid = None
#scene = None
def __init__(self, geometry, parent=None):
super(MeasureGrid, self).__init__(parent=parent)
#super().onclick.connec(self.click)
self.aLayMeasureGrid = QGridLayout(self)
self.aGsMeasureScene = QGraphicsScene(self)
self.aGsMeasureScene .setSceneRect(geometry.x(), geometry.y(), geometry.width(), geometry.height())
self.aGsMeasureScene .setBackgroundBrush(Qt.white)
self.aGvMeasureView = QGraphicsView()
self.aGvMeasureView.setScene(self.aGsMeasureScene )
self.aLayMeasureGrid.addWidget(self.aGvMeasureView)
for i in range(1,5):
rect = QRectF(100*i, 20, 80, 140)
self.addRect(rect,i)
def addRect(self, mRecMeasureBox,mIntMeasureNum):
#label = QLabel("World")
#label.setAlignment(Qt.AlignCenter | Qt.AlignCenter)
wrRectBox = WidRect(mIntMeasureNum,"Meas #" + str(mIntMeasureNum))
### CREA IL PROXY ###
gpqProxMeasure = QGraphicsProxyWidget()
gpqProxMeasure.setWidget(wrRectBox)
gpqProxMeasure.setGeometry(mRecMeasureBox)
self.aGsMeasureScene.addItem(gpqProxMeasure)
### CREA L'OGGETTO GENITORE ###
griMeasure = QGraphicsRectItem(mRecMeasureBox)
#rectangle.setFlag(QGraphicsItem.ItemIsMovable, True)
self.aGsMeasureScene.addItem(griMeasure)
gpqProxMeasure.setParentItem(griMeasure)
if __name__ == "__main__":
app = QApplication(sys.argv)
mgMeasureList = MeasureGrid(QRect(10, 10, 550, 280))
mgMeasureList.show()
app.exec_()
I would like to add:
a text into every rectangle
an icon into every rectangle
change the icon with another if I click with right button.
I try to add a QLabel but I cannot add a widget to a widget.
Can you tell me where is my error?
I create the rectangle using a proxy object because in the final version of the application they will be from 100 to 300 objects.

How create a square at any position of canvas that can be moved at any position on the canvas

I have created a square at random position in canvas, but I don't know how do I move it to somewhere else in canvas by dragging it to desired position, please suggest some edits or a new method to achieve the proposed task, I am learning while doing so.
P.S. Attached a screenshot of the output window.
import sys
from random import randint
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow,QPushButton,QWidget
from PyQt5 import QtGui
from PyQt5.QtCore import QRect,Qt
from PyQt5.QtGui import QPainter,QBrush, QPen
from PyQt5 import QtCore
class Window(QMainWindow):
def __init__(self):
super(Window,self).__init__()
title="TeeSquare"
left=500
top=200
width=500
height=400
iconName="square.jpg"
self.setWindowTitle(title)
self.setWindowIcon(QtGui.QIcon(iconName))
self.setGeometry(left, top, width, height)
self.should_paint_Rect = False
self.windowcomponents()
self.initUI()
self.show()
def initUI(self):
if self.should_paint_Rect:
self.label=QtWidgets.QLabel(self)
self.label.setText("circle")
def windowcomponents(self):
button=QPushButton("Add", self)
button.setGeometry(QRect(0, 0, 50, 28))
button.setIcon(QtGui.QIcon("Add.png"))
button.setToolTip("Create Square")
button.clicked.connect(self.paintRect)
def paintEvent(self, event):
super().paintEvent(event)
if self.should_paint_Rect:
painter = QtGui.QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.setPen(QPen(Qt.black, 5, Qt.SolidLine))
painter.drawRect(randint(0,500), randint(0,500), 100, 100)
self.initUI()
self.label.move(60,100)
def paintRect(self, painter):
self.should_paint_Rect = True
self.update()
app = QApplication(sys.argv)
Rect=Window()
Rect.show()
sys.exit(app.exec_())
The logic of creating a dynamic element is to indicate a set of specific characteristics that by modifying these, the element is modified.
In this case you could use the center of the square, the dimensions of the square, etc. and that data must be implemented through a data structure that can be created from scratch for example by creating a class that has the information of the rectangle, but in Qt it is not necessary to create that element since it already exists and is QRect.
Now that that element has been identified, you can create a QRect whose top-left is random when the button is pressed, and use that QRect to paint it.
For dragging the procedure is:
Get the mouse click position.
Verify that the click is inside the rectangle.
Calculate the position relative to the rectangle.
When moving the mouse, the position of the rectangle must be updated based on the position of the mouse press.
Considering all of the above, the solution is:
import random
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Window(QtWidgets.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.rect = QtCore.QRect()
self.drag_position = QtCore.QPoint()
button = QtWidgets.QPushButton("Add", self)
button.clicked.connect(self.on_clicked)
self.resize(640, 480)
#QtCore.pyqtSlot()
def on_clicked(self):
if self.rect.isNull():
self.rect = QtCore.QRect(
QtCore.QPoint(*random.sample(range(200), 2)), QtCore.QSize(100, 100)
)
self.update()
def paintEvent(self, event):
super().paintEvent(event)
if not self.rect.isNull():
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(QtGui.QPen(QtCore.Qt.black, 5, QtCore.Qt.SolidLine))
painter.drawRect(self.rect)
def mousePressEvent(self, event):
if self.rect.contains(event.pos()):
self.drag_position = event.pos() - self.rect.topLeft()
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
if not self.drag_position.isNull():
self.rect.moveTopLeft(event.pos() - self.drag_position)
self.update()
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
self.drag_position = QtCore.QPoint()
super().mouseReleaseEvent(event)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
Rect = Window()
Rect.show()
sys.exit(app.exec_())

Mouseover Event in PyQt5

I want to get the position of mouse while it's hovering over a label. I read this but my problem is different. I need to grab the mouse position as it hovers over my label without clicking so, mouseMoveEvent doesn't help
here's my code:
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.WindowGUI()
self.level = "Image Not Loaded Yet"
self.mouseIsClicked = False
self.top = 90
self.left = 90
self.height = 1800
self.width = 1800
self.setGeometry(self.top, self.left, self.height, self.width)
self.setWindowTitle("Manual Contact Andgle")
self.setMouseTracking(True)
mainWidget = QWidget(self)
self.setCentralWidget(mainWidget)
mainWidget.setLayout(self.finalVbox)
self.show()
def WindowGUI(self):
self.finalVbox = QVBoxLayout() # Final Layout
self.mainHBox = QHBoxLayout() # Hbox for picLable and Buttons
self.mainVBox = QVBoxLayout() # VBox for two Groupboxes
self.lineVBox = QVBoxLayout() # VBox For Line Drawing Buttons
self.fileVBox = QVBoxLayout() # VBox for file Loading and Saving Buttons
self.lineGroupbox = QGroupBox("Drawing") # GroupBox For Line Drawing Buttons
self.fileGroupbox = QGroupBox("File") # GroupBox for File Loading and Saving Buttons
self.picLable = Label(self) # Lable For showing the Image
self.piclable_pixmap = QPixmap("loadImage.png") # Setting Pixmap
self.picLable.setPixmap(self.piclable_pixmap) # setting pixmap to piclable
def mouseMoveEvent(self, QMouseEvent):
print(QMouseEvent.pos())
If you want to detect the mouse position without pressing on the widget then you must enable mouseTracking that will make the mouseMoveEvent invoked when the mouse is pressed or not, if you want to verify that it is not pressed you must use the buttons() method:
import sys
from PyQt5 import QtWidgets
class Label(QtWidgets.QLabel):
def __init__(self, parent=None):
super().__init__(parent)
self.setMouseTracking(True)
def mouseMoveEvent(self, event):
if not event.buttons():
print(event.pos())
super().mouseMoveEvent(event)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Label()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
UPDATE:
Mouse events are propagated from children to parents if the children do not consume it, that is, if the child consumes it then the parent cannot consume it. So the QLabel is consuming that event so the window will not be notified, so in this case an eventFilter should be used:
import sys
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QEvent, QObject, QPoint
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow
class HoverTracker(QObject):
positionChanged = pyqtSignal(QPoint)
def __init__(self, widget):
super().__init__(widget)
self._widget = widget
self.widget.setMouseTracking(True)
self.widget.installEventFilter(self)
#property
def widget(self):
return self._widget
def eventFilter(self, obj, event):
if obj is self.widget and event.type() == QEvent.MouseMove:
self.positionChanged.emit(event.pos())
return super().eventFilter(obj, event)
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Manual Contact Andgle")
self.picLable = QLabel(self)
self.picLable.setPixmap(QPixmap("loadImage.png"))
hover_tracker = HoverTracker(self.picLable)
hover_tracker.positionChanged.connect(self.on_position_changed)
#pyqtSlot(QPoint)
def on_position_changed(self, p):
print(p)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
You can use enterEvent.
Enter event gets called everytime the mouse is over the widget. With the event.pos() you can get the mouse coordinates.
self.label.enterEvent = lambda event: print(event.pos())

How to drag the icon when using drag and drop

Currently I have the following code that executes a drag and drop function and generates a new button by dragging and dropping another.
But what I would like to know is:
How can I make an image of him when I drag the mouse button?
something like this:
This is the code you used
In this I would like to obtain the same effect as in the gif previously shown but with the Qpushbutton
from PyQt5.QtWidgets import QPushButton, QWidget, QApplication
from PyQt5.QtCore import Qt, QMimeData
from PyQt5.QtGui import QDrag
import sys
class Button(QPushButton):
def __init__(self, title, parent):
super().__init__(title, parent)
def mouseMoveEvent(self, e):
if e.buttons() != Qt.RightButton:
return
mimeData = QMimeData()
drag = QDrag(self)
drag.setMimeData(mimeData)
drag.setHotSpot(e.pos() - self.rect().topLeft())
dropAction = drag.exec_(Qt.MoveAction)
def mousePressEvent(self, e):
super().mousePressEvent(e)
if e.button() == Qt.LeftButton:
print('press')
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setAcceptDrops(True)
self.button = Button('Button', self)
self.button.move(100, 65)
self.setWindowTitle('Click or Move')
self.setGeometry(300, 300, 280, 150)
def dragEnterEvent(self, e):
e.accept()
def dropEvent(self, e):
position = e.pos()
self.button.move(position)
self.create(position)
e.setDropAction(Qt.MoveAction)
e.accept()
def create(self,position):
print(position)
self.position = position
self.newButton = QPushButton("new",self)
self.newButton.move(self.position)
self.newButton.resize(150,50)
self.newButton.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
app.exec_()
You have to take a widget image using the grab() method then set it to QDrag using the setPixmap() method. Also I have created a method that creates a widget of the same type of the source with the same q-properties (that does not imply that it is a copy of the widget since there are non copyable elements). On the other hand it is advisable to use the right click since the left click will interfere with the clicked signal
from PyQt5 import QtCore, QtGui, QtWidgets
def fake_copy_widget(widget, parent):
t = type(widget)
w = t(parent)
mo = widget.metaObject()
for i in range(mo.propertyCount()):
prop = mo.property(i)
if prop.isWritable() and prop.isReadable():
name = prop.name()
w.setProperty(name, widget.property(name))
return w
class Button(QtWidgets.QPushButton):
def mouseMoveEvent(self, e):
if e.buttons() & QtCore.Qt.RightButton:
pos = self.mapFromGlobal(QtGui.QCursor().pos())
ba = QtCore.QByteArray()
ds = QtCore.QDataStream(ba, QtCore.QIODevice.WriteOnly)
ds << pos
mimeData = QtCore.QMimeData()
mimeData.setData("application/x-pos", ba)
pixmap = self.grab()
drag = QtGui.QDrag(self)
drag.setHotSpot(pos)
drag.setPixmap(pixmap)
drag.setMimeData(mimeData)
drag.setHotSpot(e.pos() - self.rect().topLeft())
dropAction = drag.exec_(QtCore.Qt.MoveAction)
class Example(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setAcceptDrops(True)
button = Button('Button', self)
button.move(100, 65)
self.setWindowTitle('Click or Move')
self.setGeometry(300, 300, 280, 150)
def dragEnterEvent(self, e):
if e.mimeData().hasFormat("application/x-pos"):
e.accept()
def dropEvent(self, e):
position = e.pos()
button = e.source()
mimedata = e.mimeData()
p = QtCore.QPoint()
ba = mimedata.data("application/x-pos")
ds = QtCore.QDataStream(ba)
ds >> p
self.create(QtCore.QRect(position - p, button.size()), button, self)
e.accept()
def create(self, geometry, widget, parent):
button = fake_copy_widget(widget, parent)
button.setGeometry(geometry)
button.show()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

PyQt5 Grab and save section of screen

So the idea is that I should be able to fire up the script, select a portion of the screen, then hit enter (or otherwise trigger it) to save the selection.
I've got a good bit of the code from other posts and things, but now I'm stuck. I can select any portion of the screen and resize as needed, but I can't seem to get it to recognize the "enter" key. Right now the "keyPressEvent" function is just supposed to print a message so I know it worked, but I got nothing. Any ideas?
import sys
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtCore import Qt, QPoint, QRect, QSize
from PyQt5.QtGui import QScreen
from PyQt5.QtWidgets import QApplication, QLabel, QRubberBand
class MyLabel(QtWidgets.QLabel):
def __init__(self, parent=None):
QtWidgets.QLabel.__init__(self, parent)
self.selection = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self)
def keyPressEvent(self, qKeyEvent):
print(qKeyEvent.key())
if qKeyEvent.key() == QtCore.Qt.Key_Return:
print('Enter pressed')
else:
super().keyPressEvent(qKeyEvent)
def mousePressEvent(self, event):
'''
Mouse is pressed. If selection is visible either set dragging mode (if close to border) or hide selection.
If selection is not visible make it visible and start at this point.
'''
if event.button() == QtCore.Qt.LeftButton:
position = QtCore.QPoint(event.pos())
if self.selection.isVisible():
# visible selection
if (self.upper_left - position).manhattanLength() < 20:
# close to upper left corner, drag it
self.mode = "drag_upper_left"
elif (self.lower_right - position).manhattanLength() < 20:
# close to lower right corner, drag it
self.mode = "drag_lower_right"
else:
# clicked somewhere else, hide selection
self.selection.hide()
else:
# no visible selection, start new selection
self.upper_left = position
self.lower_right = position
self.mode = "drag_lower_right"
self.selection.show()
def mouseMoveEvent(self, event):
'''
Mouse moved. If selection is visible, drag it according to drag mode.
'''
if self.selection.isVisible():
# visible selection
if self.mode is "drag_lower_right":
self.lower_right = QtCore.QPoint(event.pos())
elif self.mode is "drag_upper_left":
self.upper_left = QtCore.QPoint(event.pos())
# update geometry
self.selection.setGeometry(QtCore.QRect(self.upper_left, self.lower_right).normalized())
class mainUI(QtWidgets.QWidget):
def __init__(self):
super(mainUI, self).__init__()
self.initUI()
def initUI(self):
layout = QtWidgets.QVBoxLayout(self)
label = MyLabel(self)
pixmap = QScreen.grabWindow(app.primaryScreen(), app.desktop().winId())
label.setPixmap(pixmap)
layout.addWidget(label)
self.setLayout(layout)
geometry = app.desktop().availableGeometry()
self.setFixedSize(geometry.width(), geometry.height())
# self.setWindowFlags( self.windowFlags() | Qt.FramelessWindowHint)
self.show()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = mainUI()
sys.exit(app.exec_())
EDIT
Alright this code works, although to be honest I'm not 100% sure why.
import sys
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtCore import Qt, QPoint, QRect, QSize
from PyQt5.QtGui import QScreen
from PyQt5.QtWidgets import QApplication, QLabel, QRubberBand, QAction
class KpeWindow(QtWidgets.QLabel):
def __init__(self, parent=None):
QtWidgets.QLabel.__init__(self,parent)
main = QtWidgets.QVBoxLayout(self)
self.selection = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self)
# label = QLabel(self)
# label.setText('Test the keyPressEvent')
# main.addWidget(label)
# self.adjustSize()
# self.setLayout(main)
def keyPressEvent(self, event):
print(event.key())
if event.key() == QtCore.Qt.Key_Return:
print('yay')
#QtWidgets.QMessageBox.warning(self, 'MDI', 'keyPressEvent')
self.parent().keyPressEvent(event)
def mousePressEvent(self, event):
'''
Mouse is pressed. If selection is visible either set dragging mode (if close to border) or hide selection.
If selection is not visible make it visible and start at this point.
'''
print(event)
if event.button() == QtCore.Qt.LeftButton:
position = QtCore.QPoint(event.pos())
if self.selection.isVisible():
# visible selection
if (self.upper_left - position).manhattanLength() < 20:
# close to upper left corner, drag it
self.mode = "drag_upper_left"
elif (self.lower_right - position).manhattanLength() < 20:
# close to lower right corner, drag it
self.mode = "drag_lower_right"
else:
# clicked somewhere else, hide selection
self.selection.hide()
else:
# no visible selection, start new selection
self.upper_left = position
self.lower_right = position
self.mode = "drag_lower_right"
self.selection.show()
def mouseMoveEvent(self, event):
'''
Mouse moved. If selection is visible, drag it according to drag mode.
'''
if self.selection.isVisible():
# visible selection
if self.mode is "drag_lower_right":
self.lower_right = QtCore.QPoint(event.pos())
elif self.mode is "drag_upper_left":
self.upper_left = QtCore.QPoint(event.pos())
# update geometry
self.selection.setGeometry(QtCore.QRect(self.upper_left, self.lower_right).normalized())
class MainWindow(QtWidgets.QWidget):
def __init__(self):
super(MainWindow, self).__init__()
QtWidgets.QMainWindow.__init__(self)
#self.setWindowTitle('KeyPressEvent Test')
# main = QtWidgets.QVBoxLayout(self)
# child = KpeWindow(self)
# child.setFocusPolicy(Qt.StrongFocus)
# self.setFocusProxy(child)
# main.addWidget(child)
# child.setFocus(True)
layout = QtWidgets.QVBoxLayout(self)
label = KpeWindow(self)
pixmap = QScreen.grabWindow(app.primaryScreen(), app.desktop().winId())
label.setPixmap(pixmap)
layout.addWidget(label)
#new
label.setFocusPolicy(Qt.StrongFocus)
self.setFocusProxy(label)
label.setFocus(True)
self.setLayout(layout)
geometry = app.desktop().availableGeometry()
self.setFixedSize(geometry.width(), geometry.height())
# self.setWindowFlags( self.windowFlags() | Qt.FramelessWindowHint)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
You need to set the focus policy on the label to get keyboard events:
class MyLabel(QtWidgets.QLabel):
def __init__(self, parent=None):
...
self.setFocusPolicy(Qt.TabFocus)

Categories

Resources