【问题标题】:How to show image and text at same cell in QTableWidget in PyQt?如何在 PyQt 的 QTableWidget 中的同一单元格中显示图像和文本?
【发布时间】:2018-02-04 09:11:32
【问题描述】:

我想要一个包含 2 或 3 列的表格,其中的行在 PyQt 中显示图像和文本并排显示(我使用的是 python3.5 和 PyQt 5)。首先,我选择了 QListWidget,但它仅限于一列。我发现 QTableWidget 是最好的方法。但是当我在表格中放置一个单元格的图像时,该单元格的文本没有显示在它的底部。如何使单元格在适当的位置显示文本和图像? 这是我的代码:

self.main_table = QTableWidget(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.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.setIconSize(QSize(210,150))

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.horizontalHeader().setDefaultSectionSize(250)
self.main_table.verticalHeader().setDefaultSectionSize(250)

self.item = QTableWidgetItem(QIcon('content/img/food.png'),'Food')
self.main_table.setItem(0 , 0, self.item)

【问题讨论】:

  • 您可以指定您希望图像和文本在单元格中的显示方式
  • @eyllanesc 怎么做?
  • 例如图像相对于单元格和相对于文本的大小,它的位置,你希望它是一个图标,或者占据整个单元格,文本居中或与左侧对齐。有很多变种
  • @eyllanesc 为 QIcon 选择的任何大小,文本位于右侧,其位置不会改变。
  • 这就是你想要的吗?

标签: python qt pyqt pyqt5 qtablewidget


【解决方案1】:

最简单的方法是使用创建一个自定义小部件,在其中我们根据需要定位元素,以下代码实现图标显示在顶部,文本显示在其下方。

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(self.lbPixmap.size(),Qt.KeepAspectRatio))
        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()

然后通过setCellWidget()函数添加widget来添加它们并使用resizeColumnsToContents()resizeRowsToContents()缩放每个单元格的空间,如下所示:

class TableWidget(QTableWidget):
    def __init__(self, parent=None):
        QTableWidget.__init__(self, parent)
        self.setColumnCount(5)
        self.setRowCount(5)
        for i in range(self.columnCount()):
            for j in range(self.rowCount()):
                lb = CustomWidget(str(i)+str(j), "/path/of/image")
                self.setCellWidget(i, j, lb)

        self.resizeColumnsToContents()
        self.resizeRowsToContents()
        self.cellClicked.connect(self.onCellClicked)

    @pyqtSlot(int, int)
    def onCellClicked(self, row, column):
        w = self.cellWidget(row, column)
        print(w.text, w.img)


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    tw = TableWidget()

    tw.show()
    sys.exit(app.exec_())

【讨论】:

  • 是的。这正是我想要的形状。但我需要每个单元格的信息,如文本和名称,......这个小部件不能给我这个东西。
  • @Nimda 解释清楚,我不明白你说的文字和名字是什么意思
  • 我有一个带有此代码的函数:def populatescnte(self,item): itemnum = self.scentence_listw.count() exec("item{} = QListWidgetItem(QIcon('{}'),'{}')".format(itemnum+1,url,item.text())) exec("self.scentence_listw.addItem(item{})".format(itemnum+1)) 它在用户单击该 QTableWidget 的任何项目并将项目添加到 QListWidget 时运行。单击事件发生时,我需要该项目附带的信息。但是自定义小部件没有给我这个信息。
  • 这很简单,我更新我的答案并让你知道。 :P
猜你喜欢
  • 2019-02-09
  • 2019-02-01
  • 2023-04-02
  • 1970-01-01
  • 2015-11-09
  • 1970-01-01
  • 1970-01-01
  • 2011-01-04
  • 1970-01-01
相关资源
最近更新 更多