QAbstractScrollArea 在使用 mapToGlobal 时引入偏移量
QAbstractScrollArea introduces offset when using mapToGlobal
我有一个用于 customContextMenuRequested 的插槽,并尝试将点转换为全局点(用于上下文菜单)。如果 class 继承了 QAbstractScrollArea,则 mapToGlobal 将有偏移量(因此全局点与光标点不匹配)。
示例代码如下:
#!/usr/bin/python
import sys
from PySide import QtGui, QtCore
from PySide.QtCore import Qt
from PySide.QtGui import QApplication, QMainWindow, QCursor
class Sample(QMainWindow):
def __init__(self, parent=None):
super(Sample, self).__init__(parent)
self.resize(798, 562)
self.widget = QtGui.QScrollArea(self)
self.widget.setGeometry(QtCore.QRect(350, 290, 321, 231))
self.widget.setWidgetResizable(True)
self.scrollAreaWidgetContents = QtGui.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 315, 225))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.widget.setWidget(self.scrollAreaWidgetContents)
self.widget.setContextMenuPolicy(Qt.CustomContextMenu)
self.widget.customContextMenuRequested.connect(self.menu)
self.widget.setViewportMargins(0, 0, 0, 0)
def menu(self, point):
print 'Widget {}, {}'.format(point.x(), point.y())
glob = self.widget.mapToGlobal(point)
print 'Global {}, {}'.format(glob.x(), glob.y())
curs = QCursor.pos()
print 'Cursor {}, {}'.format(curs.x(), curs.y())
local = self.widget.mapFromGlobal(curs)
print 'Local {}, {}'.format(local.x(), local.y())
if __name__ == '__main__':
app = QApplication(sys.argv)
mySW = Sample()
mySW.show()
sys.exit(app.exec_())
我得到这样的输出:
Widget 266, 114
Global 616, 427
Cursor 619, 430
Local 269, 117
我是不是遗漏了什么,或者这是 Qt 中的错误?
我有 PySide 1.2.1 和 Qt 4.8.5。
如 customContextMenuRequested 的文档中所述,如果小部件是 QAbstractScrollArea
的子类,则需要使用视口:
glob = self.widget.viewport().mapToGlobal(point)
...
local = self.widget.viewport().mapFromGlobal(curs)
请参阅 QWidget.customContextMenuRequested
的文档。
The position pos is the position of the context menu event that the widget receives. Normally this is in widget coordinates. The exception to this rule is QAbstractScrollArea and its subclasses that map the context menu event to coordinates of the viewport().
简而言之,point
变量中的坐标不是相对于小部件,而是相对于视口。因此,您应该调用 self.widget.viewport().mapFromGlobal()
和 self.widget.viewport().mapToGlobal()
.
我有一个用于 customContextMenuRequested 的插槽,并尝试将点转换为全局点(用于上下文菜单)。如果 class 继承了 QAbstractScrollArea,则 mapToGlobal 将有偏移量(因此全局点与光标点不匹配)。
示例代码如下:
#!/usr/bin/python
import sys
from PySide import QtGui, QtCore
from PySide.QtCore import Qt
from PySide.QtGui import QApplication, QMainWindow, QCursor
class Sample(QMainWindow):
def __init__(self, parent=None):
super(Sample, self).__init__(parent)
self.resize(798, 562)
self.widget = QtGui.QScrollArea(self)
self.widget.setGeometry(QtCore.QRect(350, 290, 321, 231))
self.widget.setWidgetResizable(True)
self.scrollAreaWidgetContents = QtGui.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 315, 225))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.widget.setWidget(self.scrollAreaWidgetContents)
self.widget.setContextMenuPolicy(Qt.CustomContextMenu)
self.widget.customContextMenuRequested.connect(self.menu)
self.widget.setViewportMargins(0, 0, 0, 0)
def menu(self, point):
print 'Widget {}, {}'.format(point.x(), point.y())
glob = self.widget.mapToGlobal(point)
print 'Global {}, {}'.format(glob.x(), glob.y())
curs = QCursor.pos()
print 'Cursor {}, {}'.format(curs.x(), curs.y())
local = self.widget.mapFromGlobal(curs)
print 'Local {}, {}'.format(local.x(), local.y())
if __name__ == '__main__':
app = QApplication(sys.argv)
mySW = Sample()
mySW.show()
sys.exit(app.exec_())
我得到这样的输出:
Widget 266, 114
Global 616, 427
Cursor 619, 430
Local 269, 117
我是不是遗漏了什么,或者这是 Qt 中的错误?
我有 PySide 1.2.1 和 Qt 4.8.5。
如 customContextMenuRequested 的文档中所述,如果小部件是 QAbstractScrollArea
的子类,则需要使用视口:
glob = self.widget.viewport().mapToGlobal(point)
...
local = self.widget.viewport().mapFromGlobal(curs)
请参阅 QWidget.customContextMenuRequested
的文档。
The position pos is the position of the context menu event that the widget receives. Normally this is in widget coordinates. The exception to this rule is QAbstractScrollArea and its subclasses that map the context menu event to coordinates of the viewport().
简而言之,point
变量中的坐标不是相对于小部件,而是相对于视口。因此,您应该调用 self.widget.viewport().mapFromGlobal()
和 self.widget.viewport().mapToGlobal()
.