QTablewidget不会在PyQt5中显示新的cellWidgets

时间:2017-09-05 15:15:05

标签: python python-3.x pyqt pyqt5 qtablewidget

我的程序是用Python3.5和PyQt5编写的。我的类中有一个方法,它为QTableWidget添加了一些自定义小部件。当我从类内部调用函数时它会工作并更改QTablewidget的单元格,但是当我从另一个自定义类调用它时,它不会更改窗口小部件。我检查了,项目和索引发生了变化,但新的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),它会在我的表格中添加4个自定义小部件,但当checking类的myTableWidget方法调用populatemain时索引qtablewidget项不会改变。怎么了? 提前谢谢。

1 个答案:

答案 0 :(得分:0)

经过不少努力,我终于以这种方式解决了我的问题: 我制作了一个Qframe并将QTableWidget放入其中,然后我编辑了QTableWidget的mousePressEvent来调用下面的QFrame的mousePressEvent,如果是这个表,然后只需检查点击的开始和结束位置并做了更新的功能滑动时QTableWidget的内容。我发布这个是为了帮助其他人解决这样的问题。