2017-09-05 124 views
1

我的程序是用Python3.5和PyQt5编写的。我在我的类中添加了一些自定义小部件到QTableWidget的方法。当我从类内部调用函数并且更改QTablewidget的cellwidgets时,但是当我从另一个自定义类调用它时,它不会更改小部件。我检查了项目和索引的变化,但新的cellwidgets没有显示。问题是什么? 这是我的代码:QTablewidget在PyQt5中不显示新的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个自定义小部件添加到我的表格中,但当从类的类调​​用populatemain与其他索引qtablewidget项不会更改。怎么了? 预先感谢您。

+0

你的代码很难调试,但是一个常见的初学者错误是你没有设置列和行的数量,也就是说,如果你想在位置i,j插入这个小部件,那么这个位置必须存在,所以行数和列数必须大于aiyj,在你的情况下,在添加小部件之前使用下面的代码'self.main_table.setRowCount(2)self.main_table.setColumnCount(2)'。 – eyllanesc

+0

是的你是对的我有这段代码。在#some代码部分我已经写了这两行。因为如此,如果你看到我说的项目来表时,我点击类别项目和填充主要功能发生两次。但我不知道为什么该函数被该检查函数调用的时间没有显示新项目。 @eyllanesc – Nimda

+0

如果你没有给我看一个可以测试的代码,我不能给你任何更多的建议,因为目前的代码无法执行它,如果代码很广泛,它可以被Dropbox,驱动器等共享。 – eyllanesc

回答

0

经过大量的努力,我终于解决了我的问题是这样的: 我做了一个Qframe和它推杆的QTableWidget的,然后我editted的QTableWidget的的mousePressEvent来调用低于如果该表中的QFrame的mousePressEvent ,然后简单地检查点击的开始和结束位置,并在滑动发生时更新QTableWidget的内容。我发布这个来帮助其他人解决这个问题。