Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从选定单元格移动时,Qtablewidget未记录崩溃_Python_Pyqt_Qtablewidget - Fatal编程技术网

Python 从选定单元格移动时,Qtablewidget未记录崩溃

Python 从选定单元格移动时,Qtablewidget未记录崩溃,python,pyqt,qtablewidget,Python,Pyqt,Qtablewidget,我使用QT构建了一个GUI,在这个GUI中有一个Qtablewidget,它最初由一个空行(9列)构建。当用户在第一列中输入数据时,将添加一个新行,以确保末尾始终有一个空行。此外,如果用户从第一列删除数据,则该行将被删除(始终保留一个空行) 生成表格并执行上述操作(带格式)的代码附在下面 除了在以下情况下发生持续性崩溃外,所有这些都可以正常工作: 当有多行和时,用户双击第一列中的一个单元格进行编辑,然后不按回车/回车键单击第1列以外的另一个单元格 如果遵循此顺序,程序将关闭。根本没有生成任何错误

我使用QT构建了一个GUI,在这个GUI中有一个Qtablewidget,它最初由一个空行(9列)构建。当用户在第一列中输入数据时,将添加一个新行,以确保末尾始终有一个空行。此外,如果用户从第一列删除数据,则该行将被删除(始终保留一个空行)

生成表格并执行上述操作(带格式)的代码附在下面

除了在以下情况下发生持续性崩溃外,所有这些都可以正常工作: 当有多行时,用户双击第一列中的一个单元格进行编辑,然后不按回车/回车键单击第1列以外的另一个单元格

如果遵循此顺序,程序将关闭。根本没有生成任何错误消息,所以我很困惑是什么原因导致了它

期望的行为是,用户可以单击所述表中他们喜欢的任何位置,并且不会出现崩溃

我研究了许多线程和其他资源,没有发现任何类似的东西。我也尝试过重新调整编码,但没有成功

下面是一个示例代码(如果有点长,很抱歉,我不想去掉可能是原因的任何组合!):

请注意,列0未分配小部件/项目,因此我认为它默认为QLineEdit


如果有人能为我提供任何帮助,或者有人能为我指出其他问题的方向,我将不胜感激。

谢谢大家的帮助和建议

我最终选择了在每一行添加一个按钮。 我尝试将QlineEdit小部件设置为第一列以删除任何非类型,但是,这会干扰“cellChanged”信号。虽然我确信这是可以克服的,但我还是采纳了我认为最有利的建议

以下是我更新的最低可行代码。它仍然有点重,也不是特别整洁,但它似乎起了作用。 我希望这对某人有帮助

#####################################################################
############ qtable widget test #####################################
#####################################################################
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt


############################## Define a function to add a row to the reponse table ################
def ResponsetableRows():
    rowchanged=mygui.TableResTimetable.currentItem().row() #pick up the index of the changed row
    columnchanged=mygui.TableResTimetable.currentItem().column() #pick up the index of the changed column
 
    if columnchanged==0 and len(mygui.TableResTimetable.currentItem().text())!=0: #if the name column (id=0) has changed and is not blank then run the code to add content/ format to row

        print("doing formating stuff")
        
        #NEW              add in the new delete button to final col
        deletebutton  =  QtWidgets.QPushButton("Del")
        deletebutton.clicked.connect(DELTABrow)
        mygui.TableResTimetable.setCellWidget(rowchanged, 9, deletebutton) 

        #Then we check to see if the row at the end is blank (none type or blank in 1st cell), if not then we add a new row at the end of the table this one for the next data.
        if mygui.TableResTimetable.rowCount()==0: #if reduced to 0 rows
            mygui.TableResTimetable.insertRow(mygui.TableResTimetable.rowCount())
        elif (mygui.TableResTimetable.cellWidget(mygui.TableResTimetable.rowCount()-1,0).text())!="":
            mygui.TableResTimetable.insertRow(mygui.TableResTimetable.rowCount())    

######### NEW FUNCTION -                  identify where button clicked was and delete relevent row #####                    
def DELTABrow():
    btnClick = QtWidgets.QApplication.focusWidget()
    index = mygui.TableResTimetable.indexAt(btnClick.pos())
    if index.isValid():
        mygui.TableResTimetable.removeRow(index.row())
##################################################################

class MyGui(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        self.setGeometry(0,0,1200,400)


#########################################Basic table def######################################################
        self.TableResTimetable = QtWidgets.QTableWidget(self)
        self.TableResTimetable.setGeometry(QtCore.QRect(10, 10, 1151, 351))
        font = QtGui.QFont()
        font.setFamily("Calibri")
        font.setPointSize(11)
        self.TableResTimetable.setFont(font)
        self.TableResTimetable.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.TableResTimetable.setEditTriggers(QtWidgets.QAbstractItemView.AllEditTriggers)
        self.TableResTimetable.setProperty("showDropIndicator", False)
        self.TableResTimetable.setDragDropOverwriteMode(False)
        self.TableResTimetable.setAlternatingRowColors(False)
        self.TableResTimetable.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.TableResTimetable.setGridStyle(QtCore.Qt.DashDotLine)
        self.TableResTimetable.setWordWrap(True)
        self.TableResTimetable.setCornerButtonEnabled(False)
        self.TableResTimetable.setRowCount(1)
        self.TableResTimetable.setColumnCount(10)                        #NEW        col count increased by 1
        self.TableResTimetable.setObjectName("TableResTimetable")



#Size table for the Response Timetable
        self.TableResTimetable.setColumnWidth(0, 170) #Team member Name
        self.TableResTimetable.setColumnWidth(1, 70) #Role
        self.TableResTimetable.setColumnWidth(2, 70) #Shift
        self.TableResTimetable.setColumnWidth(3, 85) #StartDate
        self.TableResTimetable.setColumnWidth(4, 80) #Start Time
        self.TableResTimetable.setColumnWidth(5, 85) #End Date
        self.TableResTimetable.setColumnWidth(6, 80) #End Time
        self.TableResTimetable.setColumnWidth(7, 320) #Expenses Description
        self.TableResTimetable.setColumnWidth(8, 100) #Expenses Total
        self.TableResTimetable.setColumnWidth(9, 30) # NEW              col for delete button################################################
            
        self.show()

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)   #Generate and show UI
    mygui = MyGui()
    mygui.show()

###################### Signal emit and action #########################################################################
    mygui.TableResTimetable.cellChanged.connect(ResponsetableRows) # catch signal on TableResTimetable change and connect to

#############################    End call   ##########################################################
    sys.exit(app.exec_())
代码的末尾仍然保留一个空行,并允许用户删除他们选择的任何行。添加行的代码在很大程度上保持不变,但是覆盖非类型的任何逻辑语句都已删除。 我试图强调代码中新增的内容,以便清楚地了解更改的内容


虽然这对我来说是一个解决方案,但我仍然想知道自动化方法会是什么样子!如果有人有任何想法,请做后,因为我相信有更好的方法来做我所做的

仅供参考,对于我来说,代码在任何事件上都会出错(即使在窗口外单击)。这可能意味着丢失了对被垃圾回收的变量的引用。我一定不同意你说的“我不想去掉任何可能是原因的东西的组合!”:这是调试、隔离和定位问题的一部分(请参见
elif(mygui.TableResTimetable.cellWidget(mygui.TableResTimetable.rowCount()-1,0.text())=“”:
请确保您设置了“QWidget”或函数
。cellWidget()
将返回无效值,请在调试中检查该值,然后再调用
。text()
。非常感谢@SimoneMariottini,我今天下班后将有一个聚会!非常感谢@Demi Lune的评论,我刚刚重新运行了代码段,您是对的,即使在窗口外单击也会出现错误,很抱歉没有注意到。我认为原因是我的整个课程中似乎没有出现这种情况。关于调试注释,我应该更清楚,在我的调试尝试中,我删除了上面的一些代码,但在这里添加了它,以确保任何建议都有一个更完整的画面。非常感谢调试链接,非常有用!刚刚在我的问题中发现了一个故意的错误,我说“注意,列0没有分配一个小部件/项目,所以我认为它默认为QLineEdit?”我不是指Qline编辑,我只是指一个行编辑字段:-)
#####################################################################
############ qtable widget test #####################################
#####################################################################
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt


############################## Define a function to add a row to the reponse table ################
def ResponsetableRows():
    rowchanged=mygui.TableResTimetable.currentItem().row() #pick up the index of the changed row
    columnchanged=mygui.TableResTimetable.currentItem().column() #pick up the index of the changed column
 
    if columnchanged==0 and len(mygui.TableResTimetable.currentItem().text())!=0: #if the name column (id=0) has changed and is not blank then run the code to add content/ format to row

        print("doing formating stuff")
        
        #NEW              add in the new delete button to final col
        deletebutton  =  QtWidgets.QPushButton("Del")
        deletebutton.clicked.connect(DELTABrow)
        mygui.TableResTimetable.setCellWidget(rowchanged, 9, deletebutton) 

        #Then we check to see if the row at the end is blank (none type or blank in 1st cell), if not then we add a new row at the end of the table this one for the next data.
        if mygui.TableResTimetable.rowCount()==0: #if reduced to 0 rows
            mygui.TableResTimetable.insertRow(mygui.TableResTimetable.rowCount())
        elif (mygui.TableResTimetable.cellWidget(mygui.TableResTimetable.rowCount()-1,0).text())!="":
            mygui.TableResTimetable.insertRow(mygui.TableResTimetable.rowCount())    

######### NEW FUNCTION -                  identify where button clicked was and delete relevent row #####                    
def DELTABrow():
    btnClick = QtWidgets.QApplication.focusWidget()
    index = mygui.TableResTimetable.indexAt(btnClick.pos())
    if index.isValid():
        mygui.TableResTimetable.removeRow(index.row())
##################################################################

class MyGui(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        self.setGeometry(0,0,1200,400)


#########################################Basic table def######################################################
        self.TableResTimetable = QtWidgets.QTableWidget(self)
        self.TableResTimetable.setGeometry(QtCore.QRect(10, 10, 1151, 351))
        font = QtGui.QFont()
        font.setFamily("Calibri")
        font.setPointSize(11)
        self.TableResTimetable.setFont(font)
        self.TableResTimetable.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.TableResTimetable.setEditTriggers(QtWidgets.QAbstractItemView.AllEditTriggers)
        self.TableResTimetable.setProperty("showDropIndicator", False)
        self.TableResTimetable.setDragDropOverwriteMode(False)
        self.TableResTimetable.setAlternatingRowColors(False)
        self.TableResTimetable.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.TableResTimetable.setGridStyle(QtCore.Qt.DashDotLine)
        self.TableResTimetable.setWordWrap(True)
        self.TableResTimetable.setCornerButtonEnabled(False)
        self.TableResTimetable.setRowCount(1)
        self.TableResTimetable.setColumnCount(10)                        #NEW        col count increased by 1
        self.TableResTimetable.setObjectName("TableResTimetable")



#Size table for the Response Timetable
        self.TableResTimetable.setColumnWidth(0, 170) #Team member Name
        self.TableResTimetable.setColumnWidth(1, 70) #Role
        self.TableResTimetable.setColumnWidth(2, 70) #Shift
        self.TableResTimetable.setColumnWidth(3, 85) #StartDate
        self.TableResTimetable.setColumnWidth(4, 80) #Start Time
        self.TableResTimetable.setColumnWidth(5, 85) #End Date
        self.TableResTimetable.setColumnWidth(6, 80) #End Time
        self.TableResTimetable.setColumnWidth(7, 320) #Expenses Description
        self.TableResTimetable.setColumnWidth(8, 100) #Expenses Total
        self.TableResTimetable.setColumnWidth(9, 30) # NEW              col for delete button################################################
            
        self.show()

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)   #Generate and show UI
    mygui = MyGui()
    mygui.show()

###################### Signal emit and action #########################################################################
    mygui.TableResTimetable.cellChanged.connect(ResponsetableRows) # catch signal on TableResTimetable change and connect to

#############################    End call   ##########################################################
    sys.exit(app.exec_())