2017-09-05 101 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的內容。我發佈這個來幫助其他人解決這個問題。