【问题标题】:Last row of QTableWidget.itemAt() returns None instead of QTableWidgetItemQTableWidget.itemAt() 的最后一行返回 None 而不是 QTableWidgetItem
【发布时间】:2021-04-29 00:41:21
【问题描述】:

我正在使用 PyQt5 制作一个在表格中显示数据的 GUI。我想在按下“右键单击”时在特定光标位置获取项目。这是使用 contextMenuEvent 函数实现的,适用于除最后一行之外的所有行。单击表格的最后一行时,它会打印“无”而不是 QTableWidgetItem 对象。

我很困惑为什么它应该返回最后一个 QTableWidgetItem 时返回 None。

我尝试修改 event.pos() 并将其更改为 globalPos(),认为坐标可能错误,但没有任何效果。

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class CollectWindow(QMainWindow):
    def __init__(self): # window properties
        super().__init__()

        # create window
        self.setGeometry(0,0, 800, 600)
        self.centralWidget = QtWidgets.QWidget()
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralWidget)
        self.setCentralWidget(self.centralWidget)

        # create table display 
        self.table = QtWidgets.QTableWidget()
        self.horizontalLayout.addWidget(self.table)
        self.table.setColumnCount(7)
        self.table.setHorizontalHeaderLabels(["Exam Remark", "Preop", "Appt Time", "Patient Details", "Exam", "Ward", "Bed"])

        # load data into table
        self.getData()

        # show the window
        self.showMaximized()

    def contextMenuEvent(self, event):

        print (self.table.itemAt(event.pos()))

    def getData(self):

        # retrieve data from database
        result = [('Phil', 'Jones', 11256675, '08/09/1994', '09:40', '10:00', '09', '912', 'CT Pulmonary Angio', None, 'A', 'Clark Bed Bay', 'Arrived'), 
        ('Max', 'Stevenson', 11256676, '07/05/1965', '09:10', '09:30', '12', '1231', 'ECHO TTE', 'Rebook for Tommorow', 'PX', 'Tulloch 3 Bed Bay', 'Procedure Cancelled'), 
        ('Alfred', 'Bosch', 11256677, '01/01/1976', '09:40', '10:00', 'CLK9', 'CLK914', 'MRI Lumbar Spine', None, 'NP', 'Clark Bed Bay', 'Nurse Preparation'), 
        ('Gwenda', 'Gull', 11256678, '17/06/1956', '08:55', '09:15', 'EC', '03', 'XRAY Chest', None, 'F', 'Tulloch 2 Bed Bay', 'Exam Finished'), 
        ('John', 'Stalwort', 11256679, '15/07/1977', '12:00', '12:30', 'CLK8', 'CLK831', 'MRI Whole Spine', None, None, None, 'Created'), 
        ('Peter', 'Fitzgibbons', 11256680, '17/04/1944', '12:00', '12:30', '07', '733', 'CT Chest Abdomen Pelvis', 'Hold', None, None, 'Created'), 
        ('Julie', 'Bishop', 11256681, '15/6/1977', '12:30', '12:45', '09', '931', 'XRAY Chest', '', '', '', 'Created')]

        self.table.setRowCount(0)
        # plug data into table
        for row_number, row_data in enumerate(result):
            self.table.insertRow(row_number)

            examRemark = '' if row_data[9] is None else row_data[9]
            preopTime = '' if row_data[4] is None else row_data[4]
            apptTime = '' if row_data[5] is None else row_data[5]
            patientDetails = row_data[1] + ", " + row_data[0] + " - " + row_data[3] + " - " + str(row_data[2]) 
            exam = '' if row_data[8] is None else row_data[8]
            ward = '' if row_data[6] is None else row_data[6]
            bed = '' if row_data[7] is None else row_data[7]

            self.table.setItem(row_number, 0, QtWidgets.QTableWidgetItem(str(examRemark)))
            self.table.setItem(row_number, 1, QtWidgets.QTableWidgetItem(str(preopTime)))
            self.table.setItem(row_number, 2, QtWidgets.QTableWidgetItem(str(apptTime)))
            self.table.setItem(row_number, 3, QtWidgets.QTableWidgetItem(str(patientDetails)))
            self.table.setItem(row_number, 4, QtWidgets.QTableWidgetItem(str(exam)))
            self.table.setItem(row_number, 5, QtWidgets.QTableWidgetItem(str(ward)))
            self.table.setItem(row_number, 6, QtWidgets.QTableWidgetItem(str(bed)))


app = QApplication(sys.argv)
win = CollectWindow()
sys.exit(app.exec_())

【问题讨论】:

    标签: python pyqt5


    【解决方案1】:

    event.pos() 包含光标在QMainWindow 坐标系中的位置。方法itemAt 需要在您的表格视口坐标系中的位置。

    您必须使用类似的方法将事件中的位置映射到正确的坐标系:

        def contextMenuEvent(self, event):
            positionRelativeToMainWindow = event.pos()
            positionRelativeToViewport = self.table.viewport().mapFrom(self, positionRelativeToMainWindow)
            i = self.table.itemAt(positionRelativeToViewport)
            print(i.data(Qt.DisplayRole))
    

    【讨论】:

    • 这很好用,谢谢。我猜这与坐标有关,但不知道如何映射它们。
    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 2012-09-24
    • 2015-11-16
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多