2015-10-18 17 views
2

我有一個用於customContextMenuRequested的插槽,並嘗試將點轉換爲全局點(用於上下文菜單)。如果類繼承QAbstractScrollArea,則mapToGlobal將具有偏移量(因此全局點與光標點不匹配)。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的一個bug?

我有PySide 1.2.1和Qt 4.8.5。

回答

3

查看文檔QWidget.customContextMenuRequested

位置pos是小部件收到的上下文菜單事件的位置。通常這是在小部件座標中。此規則的例外是QAbstractScrollArea及其將上下文菜單事件映射到視口()的座標的子類。

總之,您的point變量中的座標不是相對於窗口小部件,而是相對於視口。因此,您應該致電self.widget.viewport().mapFromGlobal()self.widget.viewport().mapToGlobal()

1

如文檔中爲customContextMenuRequested說,你需要使用視口,如果小部件是QAbstractScrollArea一個子類:

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