PyQt:eventFilter用于在半透明窗口中获取鼠标位置

时间:2014-08-16 13:15:51

标签: qt pyqt

我想:

  1. 半透明全屏窗口(rgba(0,0,0,180))。
  2. 移动鼠标时,在标签上显示绝对位置。
  3. 用户可以按此按钮获取鼠标的绝对位置。
  4. 然而,我无法实现第二个。当鼠标移动时,标签不会更新鼠标的位置。但是我在移出标签时发现(删除layout.setMargin(0)layout.setSpacing(0)后),它可以正常工作。

    # -*- coding: utf-8 -*-
    import sys, os, math
    from PyQt4 import QtCore, QtGui
    
    class ScreenPositionLabel(QtGui.QWidget):
        def __init__(self):
            super(ScreenPositionLabel, self).__init__()
    
            self.setStyleSheet("background-color:rgba(0, 0, 0, 180); color:#fff;")
            self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
            #self.setAttribute(QtCore.Qt.WA_OpaquePaintEvent, False)
            #self.setStyleSheet("QMainWindow{opacity:0.5;}")
    
            self.label = QtGui.QLabel("Please click on screen")
            self.label.setAlignment(QtCore.Qt.AlignCenter)
    
            layout = QtGui.QHBoxLayout()
            layout.addWidget(self.label)
    
            # remove margin and padding
            layout.setMargin(0)
            layout.setSpacing(0)
    
            self.setLayout(layout)
    
            self.setMouseTracking(True)
            self.installEventFilter(self)
    
            self.label.show()
            self.show()
    
        def eventFilter(self, source, event):
            if (event.type() == QtCore.QEvent.MouseMove and
                event.buttons() == QtCore.Qt.NoButton):
                    pos = event.pos()
                    self.label.setText('Please click on screen. ( %d : %d )' % (pos.x(), pos.y()))
            elif event.type() == QtCore.QEvent.MouseButtonPress:
                pos = event.pos()
                print('( %d : %d )' % (pos.x(), pos.y()))
                self.close()
            return QtGui.QWidget.eventFilter(self, source, event)
    
    app = QtGui.QApplication(sys.argv)
    
    main_window = ScreenPositionLabel()
    app.exec_()
    

    有什么方法可以解决这个问题吗?谢谢!

1 个答案:

答案 0 :(得分:2)

你的4个问题:

  

1)我想制作:一个半透明的全屏窗口(rgba(0,0,0,180))。

是的,你可以。请使用QWidget.setWindowOpacity (self, float level)

  

2)我想制作:移动鼠标时,在标签上显示绝对位置。

我建议使用QWidget.mouseMoveEvent (self, QMouseEvent)获取鼠标的当前位置,并启用QWidget.setMouseTracking (self, bool enable)来跟踪所有鼠标移动。

QWidget.setMouseTracking (self, bool enable)

QWidget.mouseMoveEvent (self, QMouseEvent)

  

3)我想做:用户可以按下它来获得鼠标的绝对位置。

Using QWidget.mousePressEvent (self, QMouseEvent) to track when mouse press.

  

4)然而,我无法实现第二个。在鼠标上移动鼠标时,标签不会更新鼠标的位置。但是我在移出标签时发现(删除layout.setMargin(0)layout.setSpacing(0))后,它可以正常工作。

因为默认布局QLabel的高度有间距&保证金,然后实际区域不是所有区域小部件解决它是你的解决方案是好的。

您的解决方案的完整示例:

import sys
from PyQt4 import QtGui, QtCore

class QCustomLabel (QtGui.QLabel):
    def __init__ (self, parent = None):
        super(QCustomLabel, self).__init__(parent)
        self.setMouseTracking(True)
        self.setTextLabelPosition(0, 0)
        self.setAlignment(QtCore.Qt.AlignCenter)

    def mouseMoveEvent (self, eventQMouseEvent):
        self.setTextLabelPosition(eventQMouseEvent.x(), eventQMouseEvent.y())
        QtGui.QWidget.mouseMoveEvent(self, eventQMouseEvent)

    def mousePressEvent (self, eventQMouseEvent):
        if eventQMouseEvent.button() == QtCore.Qt.LeftButton:
            QtGui.QMessageBox.information(self, 'Position', '( %d : %d )' % (self.x, self.y))
        QtGui.QWidget.mousePressEvent(self, eventQMouseEvent)

    def setTextLabelPosition (self, x, y):
        self.x, self.y = x, y
        self.setText('Please click on screen ( %d : %d )' % (self.x, self.y))

class QCustomWidget (QtGui.QWidget):
    def __init__ (self, parent = None):
        super(QCustomWidget, self).__init__(parent)
        self.setWindowOpacity(0.7)
        # Init QLabel
        self.positionQLabel = QCustomLabel(self)
        # Init QLayout
        layoutQHBoxLayout = QtGui.QHBoxLayout()
        layoutQHBoxLayout.addWidget(self.positionQLabel)
        layoutQHBoxLayout.setMargin(0)
        layoutQHBoxLayout.setSpacing(0)
        self.setLayout(layoutQHBoxLayout)
        self.showFullScreen()


myQApplication = QtGui.QApplication(sys.argv)
myQTestWidget = QCustomWidget()
myQTestWidget.show()
myQApplication.exec_()