QTablewidget 在 PyQt5 中不显示新的 cellWidgets
Posted
技术标签:
【中文标题】QTablewidget 在 PyQt5 中不显示新的 cellWidgets【英文标题】:QTablewidget doesn't show new cellWidgets in PyQt5 【发布时间】:2017-09-05 15:15:04 【问题描述】:我的程序是用 Python3.5 和 PyQt5 编写的。我的类中有一个方法可以将一些自定义小部件添加到 QTableWidget。当我从类内部调用该函数时,它可以工作并更改 QTablewidget 的单元格小部件,但是当我从另一个自定义类调用它时,它不会更改小部件。我检查了一下,项目和索引发生了变化,但新的单元格小部件没有显示。问题是什么? 这是我的代码:
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 个自定义小部件,但是当myTableWidget
类中的checking
方法使用其他索引调用populatemain
时,qtablewidget 项目不会改变。怎么了?
提前谢谢你。
【问题讨论】:
你的代码很难调试,但是一个初学者常见的错误是你没有设置列数和行数,即如果你想在位置i,j,这个位置插入widget必须存在,因此行数和列数必须更大 aiyj,在您的情况下,在添加小部件之前使用以下代码self.main_table.setRowCount(2) self.main_table.setColumnCount(2)
。
是的,你是对的,我有这个代码。在#some codes
部分我已经写了这两行。因此,如果您看到我说当我单击类别项目时项目会出现在桌面上,并且填充主功能两次都会发生。但我不知道为什么该检查函数调用该函数的时间不显示新项目。 @eyllanesc
如果你不给我一个可以测试的代码,我不能给你更多的建议,因为当前的不能执行它,如果它的代码很广泛,它可以被 Dropbox 共享,驱动等。
@eyllanesc 我更新了代码。我想你现在可以用它来调试了。
我得到一个空的小部件。
【参考方案1】:
经过一番努力,我终于以这种方式解决了我的问题: 我制作了一个Qframe并将QTableWidget放入其中,然后我编辑了QTableWidget的mousePressEvent以调用该表下方的QFrame的mousePressEvent,然后简单地检查单击的开始和结束位置并制作了一个更新函数滑动时 QTableWidget 的内容。我发布此内容是为了帮助其他遇到此类问题的人。
【讨论】:
以上是关于QTablewidget 在 PyQt5 中不显示新的 cellWidgets的主要内容,如果未能解决你的问题,请参考以下文章
PyQt5 QTableWidget:右键选择列,并在上下文菜单中显示删除条目
pyqt5 QTableWidget 不会显示来自 PyEve 数据集的 id 键值
PyQt5 - 从 sqlite3 复制到 QTableWidget 的 SQL 行不显示
从 PyQt5 中的 QTableWidget 中删除单元格填充
如何从 QComboBox 中获取所选项目以显示在 PyQt5 的 QTableWidget 中? (QComboBox 有复选框来选择项目)