PDA

View Full Version : currentIndex and rowAt, and columnAt disagree



mechsin
20th June 2012, 22:02
So I have a QTableWidget which I want to have a context menu on. The context menu actions slots need to work differently depending on where I click the context menu at. So initially I was using the currentIndex method to get the appropriately selected cell. However I want to react differently if the context menu is brought up in the empty space around my cells. So then I moved to using rowAt and columnAt along with the QCursor.pos() that the context menu appeared at. The problem is the values from these two methods disagree. It seems like somehow the rowAt and columnAt are using the bottom right hand side of the cursor to map there position instead of the top left. The code below demonstrates my problem. If you right click and select current position from the menu it should print out two indices one from each method. What am I doing wrong?




from PyQt4 import QtGui, QtCore
import sys


class Test(QtGui.QTableWidget):
def __init__(self):
super(Test, self).__init__(5,5)
self.setContextMenuPolicy(QtCore.Qt.CustomContextM enu)
self.customContextMenuRequested.connect(self.ctxMe nu)

def ctxMenu(self):
menu = QtGui.QMenu(self)
a = QtGui.QAction("Current Cell", self)
menu.addAction(a)
a.triggered.connect(self.contextCurPos)
self.cursor_zero = QtGui.QCursor.pos()
menu.exec_(QtGui.QCursor.pos())

def contextCurPos(self):
pos = self.mapFromGlobal(self.cursor_zero)
col = self.columnAt(pos.x())
row = self.rowAt(pos.y())
print('Map From Cursor %d, %d' % (row, col))
model_idx = self.model().createIndex(row, col)

model_idx = self.currentIndex()
print('From Current Index %d, %d' % (model_idx.row(), model_idx.column()))
print('\n')

app = QtGui.QApplication(sys.argv)
x = Test()
x.show()
sys.exit(app.exec_())

wysota
20th June 2012, 22:16
Don't use QCursor::pos(). Read the docs on using context menus.

mechsin
21st June 2012, 13:43
Ok thanks I took a closer look and I don't know how I managed to miss that the QPoint was being passed as an argument. Anyway just in case anyone else gets hung up on this here is and example of some code that works.



from PyQt4 import QtGui, QtCore
import sys


class Test(QtGui.QTableWidget):
def __init__(self):
super(Test, self).__init__(5,5)
# If you comment out these lines the contextMenuEvent slot will be
# called when the context menu is suppose to appear. If you leave them
# active the ctxMenu def is called when the context Menu is suppose
# to appear
self.setContextMenuPolicy(QtCore.Qt.CustomContextM enu)
self.customContextMenuRequested.connect(self.ctxMe nu)

def contextMenuEvent(self, event):
menu = QtGui.QMenu(self)
a = QtGui.QAction("Current Cell", self)
menu.addAction(a)
a.triggered.connect(self.contextCurPosEvent)
self.cursor_zero = event.pos()
menu.exec_(event.globalPos())

def ctxMenu(self, position):
menu = QtGui.QMenu(self)
a = QtGui.QAction("Current Cell", self)
menu.addAction(a)
a.triggered.connect(self.contextCurPos)
self.cursor_zero = position
# Because the QTable Widget is a scroll area the position passed to
# this def is actually with respect to the viewport of the widget
# therefore you need to call the mapToGlobal from the viewport and not
# the TableWidget
menu.exec_(self.viewport().mapToGlobal(position))

def contextCurPosEvent(self):
pos = self.cursor_zero
col = self.columnAt(pos.x())
row = self.rowAt(pos.y())
print('Map From Cursor %d, %d' % (row, col))
model_idx = self.model().createIndex(row, col)

model_idx = self.currentIndex()
print('From Current Index %d, %d' % (model_idx.row(), model_idx.column()))
print('\n')

def contextCurPos(self):
pos = self.cursor_zero
col = self.columnAt(pos.x())
row = self.rowAt(pos.y())
print('Map From Cursor %d, %d' % (row, col))
model_idx = self.model().createIndex(row, col)

model_idx = self.currentIndex()
print('From Current Index %d, %d' % (model_idx.row(), model_idx.column()))
print('\n')

app = QtGui.QApplication(sys.argv)
x = Test()
x.show()
sys.exit(app.exec_())