QAbstractScrollArea在使用mapToGlobal时引入了偏移量

时间:2015-10-18 17:36:28

标签: qt position contextmenu pyside qscrollarea

我有一个customContextMenuRequested的插槽,并尝试将点转换为全局点(用于上下文菜单)。如果该类继承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。

2 个答案:

答案 0 :(得分:3)

请参阅QWidget.customContextMenuRequested的文档。

  

位置pos是窗口小部件接收的上下文菜单事件的位置。通常这是在小部件坐标中。此规则的例外是QAbstractScrollArea及其子类,它将上下文菜单事件映射到viewport()的坐标。

简而言之,dataset2.setValue(100, "John A","EMP0000"); dataset2.setValue(200, "John A","EMP0001"); dataset2.setValue(300, "John B","EMP0002"); dataset2.setValue(400, "John B","EMP0004"); 变量中的坐标不是相对于窗口小部件,而是相对于视口。因此,您应该致电pointself.widget.viewport().mapFromGlobal()

答案 1 :(得分:1)

正如customContextMenuRequested的文档中所述,如果窗口小部件是QAbstractScrollArea的子类,则需要使用视口:

    glob = self.widget.viewport().mapToGlobal(point)
    ...
    local = self.widget.viewport().mapFromGlobal(curs)