Поместить картинку в таблицу QTableWidget

Изучаю PyQt5. При работе с QTableWidget нужно в одну из ячеек положить картинку и сохранить её в папку с приложением.

Метод, который отрисовывает таблицу:

    def create_table_for_new_file(self, data):
    self.showPopupWindow.close()
    self.tableWidget.setRowCount(len(data))
    for indx, i in enumerate(data):
        for indx2, y in enumerate(i):
            # add select in row
            if indx2 == 8:
                self.create_combo_box_in_table(indx, indx2)
            elif indx2 == 11:
                # add button in row
                self.create_pushButton_in_table(indx, indx2)
            else:
                item = QtWidgets.QTableWidgetItem()
                self.tableWidget.setItem(indx, indx2, item)
                item = self.tableWidget.item(indx, indx2)
                item.setText(self._translate("MainWindow", str(y)))

    self.__sortingEnabled = self.tableWidget.isSortingEnabled()
    self.tableWidget.setSortingEnabled(self.__sortingEnabled)

Метод, который создает кнопку в последней колонки таблицы:

self.button_photo = QtWidgets.QPushButton(self.tableWidget)
    font = QtGui.QFont()
    font.setFamily("Arial")
    font.setPointSize(12)
    self.button_photo.setFont(font)
    self.button_photo.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
    self.button_photo.setText(self._translate('MainWindow', 'Загрузить'))
    self.button_photo.clicked.connect(lambda: self.add_product_photo(row, col))
    self.tableWidget.setCellWidget(row, col, self.button_photo)

По клику на кнопку в последней колонки в кнопку загружается картинка, которая сохраняется в папку с приложением.

    def add_product_photo(self, row, col):
        filter_file = "Images (*.png *.jpeg .jpg)"
        get_photo = QtWidgets.QFileDialog().getOpenFileName(self, 'Select photo', '', filter_file)[0]
        path_save = 'data/products/'
        if get_photo != '':
            makedirs(path_save, exist_ok=True)
            photo_name = get_photo.title().split('/')[-1]
            self.product_photo = path_save + str(datetime.now().microsecond) + photo_name
            try:
                image = Image.open(get_photo)
                image.save(self.product_photo)

                button = self.tableWidget.cellWidget(row, col)
                button.setText('')

                button.setIcon(QtGui.QIcon(self.product_photo))
                button.setIconSize(QtCore.QSize(50, 60))
                self.tableWidget.setRowHeight(row, 60)
            except FileNotFoundError:
                print('File can\'t open')

Данный код работает корректно. Но в случае когда нужно заменить картинку на кнопке, мне нужно удалить с папки старую картинку и загрузить новую.

Для этого хочу получить из кнопки путь к картинке, которая загружена в эту кнопку, удалить её из папки и записать туда новую выбранную картинку.

К примеру как при сохранении таблицы можно получить значение ячейки item.text().
Так же хочу получить путь к картинке из ячейки где лежит кнопка.


Ответы (1 шт):

Автор решения: S. Nick

Я вам покажу два варианта как поместить картинку в таблицу QTableWidget, но я очень надеюсь, что в следующий раз вы предоставите минимально-воспроизводимый пример, который демонстрирует проблему.

import sys
import os
import shutil
from datetime import datetime
from PyQt5.Qt import *


class IconDelegate(QStyledItemDelegate):
    def initStyleOption(self, option, index):
        super(IconDelegate, self).initStyleOption(option, index)
        option.decorationSize = option.rect.size()
        

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        rows = 4
        columns = 4
        
        self.tableWidget = QTableWidget(rows, columns)
        self.tableWidget.setHorizontalHeaderLabels(
            ['Изображение 1', 'Изображение 2', 'Кнопка', 'Скрытая колонка'])
        self.tableWidget.verticalHeader().setDefaultSectionSize(100)
        self.tableWidget.horizontalHeader().setDefaultSectionSize(200)
        self.setCentralWidget(self.tableWidget)

        for row in range(rows):
            self.button = QPushButton('Загрузить \nновую \nкартинку', self)
            self.tableWidget.setCellWidget(row, 2, self.button)
            self.button.clicked.connect(lambda ch, row=row: self.button_pushed(row))
            
            self.tableWidget.setItem(row, 3, QTableWidgetItem(''))  

        delegate = IconDelegate(self.tableWidget)
        self.tableWidget.setItemDelegateForColumn(1, delegate) 
        
        # void QTableView::setColumnHidden(int column, bool hide)
        # Если hide истинно, данный столбец будет скрыт; в противном случае он будет показан.
        self.tableWidget.setColumnHidden(3, True) 
        

    def button_pushed(self, row):    
        filter_file = "Images (*.png *.jpeg .jpg)"
        get_photo = QFileDialog().getOpenFileName(
            self, 
            'Select photo', 
            '', 
            filter_file
        )[0]
        
        path_save = 'data_test/products/'                            # 'data/products/'
        
        if get_photo:
            os.makedirs(path_save, exist_ok=True)
            
#            photo_name = get_photo.title().split('/')[-1]
            photo_name = get_photo.split('/')[-1]
            
            product_photo = path_save + str(datetime.now().microsecond) + photo_name
            shutil.copyfile(get_photo, product_photo)
            old_path = self.tableWidget.item(row, 3).text()
            
            self.update_photo(product_photo, row)
            
            if old_path:
                os.remove(old_path)
            
    def update_photo(self, file, row): 
        label = QLabel() 
        pixmap = QPixmap(file)
        _size = QSize(200, 100) 
        label.setPixmap(pixmap.scaled(_size, Qt.KeepAspectRatio))
        self.tableWidget.setCellWidget(row, 0, label)
            
        item = QTableWidgetItem(QIcon(file), "")
        self.tableWidget.setItem(row, 1, item)            
            
        self.tableWidget.setItem(row, 3, QTableWidgetItem(file))            


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    w.resize(850, 500)
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка