2017-12-16 77 views
1

PyQt5로 앱을 개발 중이며 QTableView에서 오른쪽 클릭의 위치를 ​​행 번호로 변환하는 방법을 찾을 수 없습니다. 구현 한 방법은 QPoint 커서 위치에서 rowAt 메서드를 사용하는 것으로, 클릭 한 실제 행 번호와 오프셋이있는 것처럼 보이는 행 번호가 표시됩니다. 나는 주변을 둘러 보았지만 명확한 해결책을 찾지 못했습니다. 스크롤 영역과 관련이있는 것 같습니다. 내 코드 예제는 다음과 같습니다. Qt는 디자이너 생성QTableView의 rigth-click에서 행 번호를 얻는 방법은 무엇입니까?

하는 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있어서, 로컬 좌표를 사용한다. 그래서 올바른 Y 값을 얻을 수 mapFromGlobal를 사용해야합니다 반환 된 행이 입니다

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)) 

하는 것으로 수직 헤더 라벨과는 달리,을 제로.