QTablewidget 在 PyQt5 中不显示新的 cellWidgets

QTablewidget doesn't show new cellWidgets in PyQt5

我的程序是用Python3.5 和 PyQt5 编写的。我的 class 中有一个方法可以将一些自定义小部件添加到 QTableWidget。当我从 class 内部调用该函数时,它可以工作并更改 QTablewidget 的 cellwidgets,但是当我从另一个自定义 class 调用它时,它不会更改小部件。我检查了一下,项目和索引发生了变化,但新的 cellwidgets 没有显示。问题是什么? 这是我的代码:

class mainmenupage(QWidget):
    elist = []
    def __init__(self):
        #the main window widget features
        self.setObjectName("mainpage")
        self.resize(800, 480)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(sizePolicy)
        self.setMinimumSize(QSize(800, 480))
        self.setMaximumSize(QSize(800, 480))

        #the QTreeWidget features
        self.category_tree = QTreeWidget(self)
        self.category_tree.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.category_tree.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.category_tree.setGeometry(QRect(630, 90, 161, 381))
        self.category_tree.setLayoutDirection(Qt.RightToLeft)
        self.category_tree.setLocale(QLocale(QLocale.Persian, QLocale.Iran))
        self.category_tree.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.category_tree.setUniformRowHeights(False)
        self.category_tree.setColumnCount(1)
        self.category_tree.setObjectName("category_tree")
        self.category_tree.headerItem().setText(0, "1")
        self.category_tree.setFrameShape(QFrame.NoFrame)
        self.category_tree.header().setVisible(False)
        self.category_tree.header().setSortIndicatorShown(False)
        self.category_tree.setFocusPolicy(Qt.NoFocus))

        #the QTableWidget features. It comes from the custom class myTableWidget
        self.main_table = myTableWidget(self)
        self.main_table.setGeometry(QRect(20, 140, 600, 330))
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.main_table.sizePolicy().hasHeightForWidth())
        self.main_table.setSizePolicy(sizePolicy)
        self.main_table.setMinimumSize(QSize(0, 0))
        self.main_table.setLayoutDirection(Qt.LeftToRight)
        self.main_table.setLocale(QLocale(QLocale.Persian, QLocale.Iran))
        self.main_table.setInputMethodHints(Qt.ImhNone)
        self.main_table.setFrameShape(QFrame.NoFrame)
        self.main_table.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.main_table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.main_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.main_table.setTabKeyNavigation(False)
        self.main_table.setShowGrid(False)
        self.main_table.setCornerButtonEnabled(False)
        self.main_table.setUpdatesEnabled(True)

        self.main_table.setRowCount(2)
        self.main_table.setColumnCount(2)

        self.main_table.setObjectName("main_table")
        self.main_table.horizontalHeader().setVisible(False)
        self.main_table.horizontalHeader().setHighlightSections(False)
        self.main_table.verticalHeader().setVisible(False)
        self.main_table.verticalHeader().setHighlightSections(False)
        self.main_table.setFocusPolicy(Qt.NoFocus)
        self.main_table.setSelectionMode(QAbstractItemView.NoSelection)


        self.main_table.horizontalHeader().setDefaultSectionSize(300)
        self.main_table.verticalHeader().setDefaultSectionSize(165)

        self.category_tree.itemPressed.connect(self.insertdata)

    def insertdata(self,subcat):
        #get the text of clicked item from qtreewidget
        item = self.category_tree.currentItem().text(0)
        #get data from DB
        datas = self.conn.retrievedata('*','words',"subcat='{}'".format(item))
        #check if the list of copied data is empty or not
        if mainmenupage.elist != []:
            del mainmenupage.elist[:]
        #if the list is empty, the data received from DB appends to it
        if mainmenupage.elist == []:
            for data in datas:
                mainmenupage.elist.append(data)
            #delete the first index of copied list because it isn't needed here
            mainmenupage.elist = mainmenupage.elist[1:]
        # calls the populatemain function for populating qtablewidget with these datas with a custom index e.g. index 5 to 9.
        self.populatemain(5,9)

    def populatemain(self,startindexdata,endindexdata):
        #make a list for indexes of items that will be added to qtablewidget
        mtl=[]
        for i in range(2):
            for j in range(2):
                mtl.append(i)
                mtl.append(j)
        #adding custom widgets as cellWidgets to qtablewidget
        for index, my in enumerate(zip(*[iter(mtl)]*2)):
            if mainmenupage.elist != []:
                data = mainmenupage.elist[startindexdata:endindexdata][index]

                exec("self.iteM{} = CustomWidget('{}','content/img/food.png')".format(data[0],data[4]))
                exec("self.main_table.setCellWidget({} ,{}, self.iteM{})".format(*my,data[0]))


class myTableWidget(QTableWidget):
    def checking(self):
        if (self.endgingposx - self.startingposx) <= -50:
        #a custom function for checking that if the user made a swipe to left on the qtablewidget for chaning it's content
            if mainmenupage.elist != []:
                #make an instance from the previous class for accessing to populatemain method
                x = mainmenupage()
                #calling populatemain method for changing widgets in qtablewidget with the items made from different indexes of the copied data list e.g. indexes 0 to 4. but i don't know why this doesn't change the items. The populatemain function runs correctly it can be checked by putting print statement in it but it doesn't change the Qtablewidget contents.
                x.populatemain(0,4)
    def mousePressEvent(self,event):
        super().mousePressEvent(event)
        self.startingposx = event.x()
    def mouseReleaseEvent(self,event):
        super().mouseReleaseEvent(event)
        self.endgingposx = event.x()
        self.checking()

class CustomWidget(QWidget):
     def __init__(self, text, img, parent=None):
        QWidget.__init__(self, parent)

        self._text = text
        self._img = img

        self.setLayout(QVBoxLayout())
        self.lbPixmap = QLabel(self)
        self.lbText = QLabel(self)
        self.lbText.setAlignment(Qt.AlignCenter)

        self.layout().addWidget(self.lbPixmap)
        self.layout().addWidget(self.lbText)

        self.initUi()

    def initUi(self):
         self.lbPixmap.setPixmap(QPixmap(self._img).scaled(260,135,Qt.IgnoreAspectRatio,transformMode = Qt.SmoothTransformation))
        self.lbText.setText(self._text)


    @pyqtProperty(str)
    def img(self):
        return self._img

    @img.setter
    def total(self, value):
        if self._img == value:
            return
        self._img = value
        self.initUi()

    @pyqtProperty(str)
    def text(self):
        return self._text

    @text.setter
    def text(self, value):
        if self._text == value:
            return
        self._text = value
        self.initUi()

self.category_tree 是一个 QTreeWidget

self.main_table 是一个 QTableWidget

完成我的问题。当我单击其中一个 self.category_tree items 时,它会调用 insertdata。在 insertdata 的最后一行,我调用 self.populatemain(5,9) 它向我的 table 添加了 4 个自定义小部件,但是当来自 myTableWidget class 的 checking 方法时使用其他索引调用 populatemain qtable 小部件项目不会更改。怎么了? 提前谢谢你。

经过一番努力终于解决了我的问题: 我制作了一个Qframe并将QTableWidget放入其中,然后我编辑了QTableWidget的mousePressEvent以调用下面的QFrame的mousePressEvent if this table,然后简单地检查点击的开始和结束位置并制作滑动发生时更新 QTableWidget 内容的函数。我发布这篇文章是为了帮助其他遇到此类问题的人。