2017-12-16 21 views
1

私はPyQt5でアプリケーションを開発しており、QTableViewの右クリックの位置を行番号に変換する方法を見つけることができません。 QPointカーソル位置のrowAtメソッドを使用して実装した方法では、クリックされた実際の行番号とオフセットがあるような行番号が表示されます。私は周りを見回してきましたが、明確な解決策を得ることができませんでした。スクロール領域と関係があるように聞こえます。私のコードの例は以下の通りです。QTableViewのrigth-clickから行番号を取得する方法は?

のQt Designerで生成されたUIコード:

from PyQt5 import QtCore, QtGui, QtWidgets 

class Ui_MainWindow(object): 
    def setupUi(self, MainWindow): 
     MainWindow.setObjectName("MainWindow") 
     MainWindow.setWindowModality(QtCore.Qt.NonModal) 
     MainWindow.resize(941, 767) 
     MainWindow.setMinimumSize(QtCore.QSize(922, 767)) 
     MainWindow.setMaximumSize(QtCore.QSize(1900, 1200)) 
     MainWindow.setAutoFillBackground(False) 
     MainWindow.setAnimated(False) 
     self.MyWindows = QtWidgets.QWidget(MainWindow) 
     self.MyWindows.setEnabled(True) 
     self.MyWindows.setMinimumSize(QtCore.QSize(921, 726)) 
     self.MyWindows.setMaximumSize(QtCore.QSize(1900, 1200)) 
     self.MyWindows.setObjectName("MyWindows") 
     self.layoutWidget = QtWidgets.QWidget(self.MyWindows) 
     self.layoutWidget.setGeometry(QtCore.QRect(10, 0, 911, 441)) 
     self.layoutWidget.setObjectName("layoutWidget") 
     self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget) 
     self.gridLayout.setContentsMargins(0, 0, 0, 0) 
     self.gridLayout.setObjectName("gridLayout") 
     self.tableView = QtWidgets.QTableView(self.layoutWidget) 
     self.tableView.setEnabled(True) 
     sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) 
     sizePolicy.setHorizontalStretch(1) 
     sizePolicy.setVerticalStretch(1) 
     sizePolicy.setHeightForWidth(self.tableView.sizePolicy().hasHeightForWidth()) 
     self.tableView.setSizePolicy(sizePolicy) 
     self.tableView.setMinimumSize(QtCore.QSize(900, 400)) 
     font = QtGui.QFont() 
     font.setPointSize(10) 
     self.tableView.setFont(font) 
     self.tableView.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents) 
     self.tableView.setAlternatingRowColors(True) 
     self.tableView.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) 
     self.tableView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) 
     self.tableView.setGridStyle(QtCore.Qt.NoPen) 
     self.tableView.setSortingEnabled(False) 
     self.tableView.setObjectName("tableView") 
     self.tableView.horizontalHeader().setCascadingSectionResizes(True) 
     self.tableView.horizontalHeader().setSortIndicatorShown(False) 
     self.tableView.horizontalHeader().setStretchLastSection(True) 
     self.tableView.verticalHeader().setVisible(True) 
     self.tableView.verticalHeader().setCascadingSectionResizes(True) 
     self.tableView.verticalHeader().setHighlightSections(True) 
     self.tableView.verticalHeader().setSortIndicatorShown(False) 
     self.tableView.verticalHeader().setStretchLastSection(True) 
     self.gridLayout.addWidget(self.tableView, 1, 1, 1, 1) 
     MainWindow.setCentralWidget(self.MyWindows) 

     self.retranslateUi(MainWindow) 
     QtCore.QMetaObject.connectSlotsByName(MainWindow) 

    def retranslateUi(self, MainWindow): 
     _translate = QtCore.QCoreApplication.translate 
     MainWindow.setWindowTitle(_translate("MainWindow", "Thib Imave Smoother V0.2")) 

メインコード:あなたはグローバル座標を使用しているのに対し、

from PyQt5.QtCore import * 
from PyQt5.QtWidgets import QMainWindow, QSizePolicy, QHeaderView, QFileSystemModel, QMenu, QAction 
# QtDesigner generated code imports 
from UI import * 

class ShowTableView: 

    def __init__(self, guiObject): 
     self._gui = guiObject # store QWidget from Gui class 
     #initialize fake data for testing 
     self.my_data = [["test" for x in range(7)] for x in range(5000)] 
     self.tm = MyTableModel(self.my_data) 
     self._gui.tableView.setModel(self.tm) 
     header = self._gui.tableView.horizontalHeader() 
     header.setSectionResizeMode(QHeaderView.ResizeToContents) # have columns width adjusted to content 

class MyTableModel(QAbstractTableModel): 
    def __init__(self, my_data, parent=None, *args): 
     QAbstractTableModel.__init__(self, parent) 
     self.my_data = my_data 
     self.title_list = ["on","two","three","four","five","six","seven"] 

    def rowCount(self, parent): 
     return len(self.my_data) 

    def columnCount(self, parent): 
     return len(self.my_data[0]) 

    def data(self, index, role): 
     if not index.isValid(): 
      return QVariant() 
     elif role != Qt.DisplayRole: 
      return QVariant() 
     else: # 
      return QVariant(self.my_data[index.row()][index.column()]) 

    def headerData(self, col, orientation, role): 
     if orientation == Qt.Horizontal and role == Qt.DisplayRole: 
      return QVariant(self.title_list[col]) 
     elif orientation == Qt.Vertical and role == Qt.DisplayRole: 
      return QVariant(col + 1) 

class Gui(QMainWindow, Ui_MainWindow): 
    def __init__(self, parent=None): 
     super(Gui, self).__init__(parent) 
     self.setupUi(self) 
     self.myTable = ShowTableView(self) 

    def contextMenuEvent(self, QContextMenuEvent): 
     self.menu = QMenu(self) 
     removeAction = QAction('Remove', self) 
     self.menu.addAction(removeAction) 
     removeAction.triggered.connect(lambda: self.remove_row_from_rigth_click(QtGui.QCursor.pos())) 
     self.menu.popup(QtGui.QCursor.pos()) 

    def remove_row_from_rigth_click(self, event,q_point): 
     row = self.tableView.rowAt(q_point.y()) 
     print("row =" + str(row)) # HERE I GET WRONG VALUE WITH AN "RANDOM" OFFSET - IF I CLICK ROW 10 I GET 16 ! 

if __name__ == "__main__": 

    app = QtWidgets.QApplication(sys.argv) 
    ui = Gui() 
    ui.show() 
    sys.exit(app.exec_()) 

答えて

0

rowAt方法は、ローカル座標を使用しています。

class Gui(QMainWindow, Ui_MainWindow): 
    ... 
    def contextMenuEvent(self, event): 
     ... 
     pos = event.globalPos() 
     removeAction.triggered.connect(
      lambda: self.remove_row_from_rigth_click(pos)) 
     self.menu.popup(pos) 

    def remove_row_from_rigth_click(self, q_point): 
     row = self.tableView.rowAt(
      self.tableView.viewport().mapFromGlobal(q_point).y()) 
     print("row =" + str(row)) 

注意返された行は、垂直ヘッダ・ラベルとは異なり、ゼロベースであること:だから、あなたは正しいY値を取得するためにmapFromGlobalを使用する必要があります。

関連する問題