我正在用PyQt编写一个截图实用程序,其想法是截取整个桌面,然后将其显示在QLabel中,使窗口全屏显示,用户通过鼠标选择一个区域。
是否可以使用QLabel高效地完成此操作?我希望橡皮筋留在屏幕上,它仍然可以调整。在这种情况下,我是否必须使用QGraphicsScene?
期望效果: http://gfycat.com/SkinnyObeseAquaticleech
这是我到目前为止所拥有的
import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt, QPoint, QRect, QSize
from PyQt4.QtGui import QPixmap, QApplication, QLabel, QRubberBand
class MyLabel(QLabel):
def __init__(self, parent=None):
QLabel.__init__(self, parent)
self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
self.origin = QPoint()
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.origin = QPoint(event.pos())
self.rubberBand.setGeometry(QRect(self.origin, QSize()))
self.rubberBand.show()
def mouseMoveEvent(self, event):
if not self.origin.isNull():
self.rubberBand.setGeometry(
QRect(self.origin, event.pos()).normalized())
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
self.rubberBand.hide()
class mainUI(QtGui.QWidget):
def __init__(self):
super(mainUI, self).__init__()
self.initUI()
def initUI(self):
layout = QtGui.QVBoxLayout(self)
label = MyLabel(self)
pixmap = QPixmap.grabWindow(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 = QtGui.QApplication(sys.argv)
window = mainUI()
sys.exit(app.exec_())
答案 0 :(得分:3)
你的方法已经相当远了,我认为用QLabel实现你想要的东西是可能的。我扩展了你的例子,即使释放鼠标后橡皮筋也会停留在屏幕上,你可以拖动它的左上角和右下角。
您可以进一步扩展它以拖动其他角落和侧面并显示大小在中间的标签。
from PyQt4 import QtGui, QtCore
class RubberbandEnhancedLabel(QtGui.QLabel):
def __init__(self, parent=None):
QtGui.QLabel.__init__(self, parent)
self.selection = QtGui.QRubberBand(QtGui.QRubberBand.Rectangle, self)
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())
app = QtGui.QApplication([])
screen_pixmap = QtGui.QPixmap.grabWindow(app.desktop().winId())
window = QtGui.QWidget()
layout = QtGui.QVBoxLayout(window)
label = RubberbandEnhancedLabel()
label.setPixmap(screen_pixmap)
layout.addWidget(label)
geometry = app.desktop().availableGeometry()
window.setFixedSize(geometry.width(), geometry.height())
window.show()
app.exec_()