Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to move a cell widget location in TableWidget?



  • When I inserted some new rows to a table and set them to be selected, I found the positions of all buttons in the TableWidget were moved to the wrong place.

    The interesting thing is if I only selected one row, the position of the buttons would not be changed.

    # set to multiselction mode
    tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
    # select a row
    tableWidget.selectRow(row)
    

    So my question is how to set such cell widget to be moved like what happened in my screenshots below and how to reset them back to the right location?

    alt text

    alt text

    UPDATE:

    After playing around with it, I found a solution to my problem.

    So after inserting some records, I call sortItems() to the table on the button column, then all buttons will display in the right position. Don't know why, but it works for me.

    tableWidget.sortItems(0)
    


  • @Zac15
    Show your code, including what those buttons are and how you add them into the table. If you have added any stylesheet rules affecting the table, or the buttons, show that too.

    As a separate matter, you might (or might not) decide you want row selection not to show the button columns as selected, only the remaining non-button columns on selected rows. Which can be done by marking those cells as unselectable, which as a side-effect may get rid of the issue.



  • Thank you @JonB . My code was written in QGIS and I tried to reproduce an easy one outside QGIS, but the issue didn't come up. (As shown below)

    Can you tell me how to make a cell widget unselectable? I think it's a possible solution to my problem.

    # -*- coding: utf-8 -*-
    
    # Form implementation generated from reading ui file 'disassociation_table.ui'
    #
    # Created by: PyQt5 UI code generator 5.11.3
    #
    # WARNING! All changes made in this file will be lost!
    
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    class Ui_Dialog(object):
        def setupUi(self, Dialog):
            Dialog.setObjectName("Dialog")
            Dialog.resize(400, 200)
            self.gridLayout = QtWidgets.QGridLayout(Dialog)
            self.gridLayout.setObjectName("gridLayout")
    
            # add a button on the window
            self.pushButton = QtWidgets.QPushButton(Dialog)
            self.pushButton.setText("add rows")
            self.gridLayout.addWidget(self.pushButton, 1, 6, 1, 1)
    
            self.tableWidget = QtWidgets.QTableWidget(Dialog)
            self.tableWidget.setMinimumSize(QtCore.QSize(0, 0))
            self.tableWidget.setAlternatingRowColors(True)
            self.tableWidget.setColumnCount(0)
            self.tableWidget.setObjectName("tableWidget")
            self.tableWidget.setRowCount(0)
            self.tableWidget.horizontalHeader().setVisible(True)
            self.tableWidget.horizontalHeader().setDefaultSectionSize(150)
            self.tableWidget.horizontalHeader().setMinimumSectionSize(39)
            self.tableWidget.horizontalHeader().setStretchLastSection(True)
            self.tableWidget.verticalHeader().setDefaultSectionSize(45)
            self.tableWidget.verticalHeader().setMinimumSectionSize(35)
            self.tableWidget.setMinimumSize(450,260)
            # set column count
            self.tableWidget.setColumnCount(3)
            # add two rows
            self.tableWidget.setRowCount(2)
            self.tableWidget.horizontalHeader().setStretchLastSection(True)
            self.tableWidget.setColumnWidth(0, 120)
            self.tableWidget.setColumnWidth(1, 120)
            self.tableWidget.setColumnWidth(2, 120)
            for i in range(2):
                # button 1 of column1
                pushButton1 = QtWidgets.QPushButton(self.tableWidget)
                pushButton1.setText('a' + str(i))
                self.tableWidget.setCellWidget(i, 0, pushButton1)
    
                # button 2 of column2
                pushButton2 = QtWidgets.QPushButton(self.tableWidget)
                pushButton2.setText('b' + str(i))
                self.tableWidget.setCellWidget(i, 1, pushButton2)
    
                # an item of column3
                qItem = QtWidgets.QTableWidgetItem()
                # save qItem as integer so that it can be sorted
                qItem.setData(QtCore.Qt.DisplayRole, i)
                self.tableWidget.setItem(i, 2, qItem)
                qItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
    
            self.gridLayout.addWidget(self.tableWidget, 0, 0, 1, 7)
    
    
            self.retranslateUi(Dialog)
            QtCore.QMetaObject.connectSlotsByName(Dialog)
    
        def retranslateUi(self, Dialog):
            _translate = QtCore.QCoreApplication.translate
            Dialog.setWindowTitle(_translate("Dialog", ""))
            self.tableWidget.setSortingEnabled(True)
    
        def addRows(self):
            # change to mutiple selection mode
            self.tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
            
            # insert three new rows and select them
            for i in range(3):
                row = self.insertRow()
                # select the row
                self.tableWidget.selectRow(row)
            
            # change select mode back
            self.tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
        
        def insertRow(self):
             # insert a row to the table
            rowCount = self.tableWidget.rowCount()
            self.tableWidget.insertRow(rowCount)
            
            # row to insert 
            row = self.tableWidget.rowCount() - 1
    
            # button 1 of column1
            pushButton1 = QtWidgets.QPushButton(self.tableWidget)
            pushButton1.setText('a' + str(row))
            self.tableWidget.setCellWidget(row, 0, pushButton1)
            pushButton1.clicked.connect(lambda: print("button1"))
    
            # button 2 of column2
            pushButton2 = QtWidgets.QPushButton(self.tableWidget)
            pushButton2.setText('b' + str(row))
            self.tableWidget.setCellWidget(row, 1, pushButton2)
            pushButton2.clicked.connect(lambda: print("button2"))
    
            # an item of column3
            qItem = QtWidgets.QTableWidgetItem(str(row))
            self.tableWidget.setItem(row, 2, qItem)
            qItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditable)
        
            return row
    
    
    if __name__ == "__main__":
        import sys
        app = QtWidgets.QApplication(sys.argv)
        Dialog = QtWidgets.QDialog()
        ui = Ui_Dialog()
        ui.setupUi(Dialog)
        Dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
        Dialog.setWindowFlags(Dialog.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
        ui.pushButton.clicked.connect(ui.addRows)
        Dialog.show()
        sys.exit(app.exec_())
        
    

Log in to reply