Название: Сохранение и открытие QTableWidget
Отправлено: Dr.robot от Январь 29, 2017, 15:37
Здравствуйте. У меня вот такой вопрос, как сохранить таблицу со всем ее содержимым (иконки, картинки, чекбоксы итд...) Я смог сохранять таблицу с содержанием текста все работает, но когда я вставляю картинки то их по началу вообще не сохраняло. Потом я узнал что надо задать роль для картинки, задал но теперь я сохраняю в ячейке PyQt4.QtGui.QTableWidgetItem object at 0x0000000003DC2EE8 это объект памяти. Собственно как сохранить в таблице не только текст. Вот код урезаный что бы влез Python import sys from PyQt4.QtCore import * from PyQt4.QtGui import * from functools import partial import xlwt import xlrd class My_Widget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.table = QTableWidget(self) self.table.setRowCount(20) self.table.setColumnCount(20) self.table.setGeometry(0, 29, 1600, 1600) self.table.show() self.table.horizontalHeader().hide() self.table.verticalHeader().hide() self.table.setColumnWidth(0, 30) self.table.setRowHeight(0, 30) self.table.resizeColumnsToContents() delegate = MyDelegate() self.table.setItemDelegate(delegate) #Цвет таблицы и стиль self.table.setStyleSheet("gridline-color: #FFC0CB") self.table.setGridStyle(1) self.table.setFrameStyle(QFrame.NoFrame) #--------------------------------------------- self.setGeometry(300, 300, 800, 600) self.setWindowTitle('icon') #--------------------------------------------- self.lay = QHBoxLayout() self.lay.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.lay.setMargin(0) self.lay.setSpacing(0) self.setLayout(self.lay) self.BUTTNS = [ {'text': u'', 'img': 'sym1.png', 'ico': 'sym1.png'}, {'text': u'', 'img': 'sym2.png', 'ico': 'sym2.png'}] #--------------------------------------------- for i in self.BUTTNS: i["btn"] = QPushButton(i["text"]) i["btn"].setIcon(QIcon(i["ico"])) i["btn"].clicked.connect(partial(self.on_clicked_btn, QPixmap(i["img"]))) self.lay.addWidget(i["btn"]) #--------------------------------------------- self.btn = QPushButton("save xls", self) self.btn.setGeometry(75, 0, 80, 30) self.btn.sizeHint() self.connect(self.btn, SIGNAL("clicked()"), self.save_file) self.btn2 = QPushButton("open xls", self) self.btn2.setGeometry(150, 0, 80, 30) self.btn2.sizeHint() self.connect(self.btn2, SIGNAL("clicked()"), self.open_file) #--------------------------------------------- def on_clicked_btn(self, img): item = QTableWidgetItem() item.setData(Qt.DecorationRole, img) self.table.setItem(self.table.currentRow(), self.table.currentColumn(), item) #--------------------------------------------- #-------------------------------------------- def save_file(self): filename = (QFileDialog.getSaveFileName(self, 'Сохранить', '', ".xls(*.xls)")) wbk = xlwt.Workbook() sheet = wbk.add_sheet("схема", cell_overwrite_ok=True) self.s_f(sheet) wbk.save(filename) def s_f(self, sheet): for currentColumn in range(self.table.columnCount()): for currentRow in range(self.table.rowCount()): my_icon = self.table.item(currentRow, currentColumn) sheet.write(currentRow, currentColumn, str(my_icon or '')) #------------------------------------------- def open_file(self): filename = QFileDialog.getOpenFileName(self, 'Открыть', '', '.xls(*.xls)') book = xlrd.open_workbook(filename) sheet = book.sheet_by_index(0) data = [[sheet.cell_value(r, c)for c in range(sheet.ncols)]for r in range(sheet.nrows)] for row, columnvalues in enumerate(data): for column, value in enumerate(columnvalues): item = QTableWidgetItem() item.setData(Qt.DisplayRole, str(value)) self.table.setItem(row, column, item) #--------------------Делегат для ячейки class MyDelegate(QStyledItemDelegate): def paint(self, painter, option, index): img = index.model().data(index, Qt.DecorationRole) if img is None: super().paint(painter, option, index) return rect = option.rect w, h = rect.size().width(), rect.size().height() img = img.scaled(w, h, Qt.KeepAspectRatio, Qt.SmoothTransformation) painter.drawPixmap(rect, img) item_option = QStyleOptionViewItem(option) self.initStyleOption(item_option, index) #Для полупрозрачности выделения if item_option.state & QStyle.State_Selected: color = item_option.palette.color(QPalette.Highlight) color.setAlpha(180) painter.save() painter.setPen(Qt.NoPen) painter.setBrush(color) painter.drawRect(rect) painter.restore() # super().paint(painter, option, index) #-------------- if __name__ == '__main__': app = QApplication(sys.argv) widget = My_Widget() widget.show() sys.exit(app.exec_())
Может не так вставляю картинку а может не так сохраняю или и то и другое. Или может есть другой способ сохранения ?
Название: Re: Сохранение и открытие QTableWidget
Отправлено: gil9red от Январь 30, 2017, 08:53
Используйте у QTableWidgetItem метод/свойство для получения его текста, а str(my_icon or '') вам точно не поможет
Мне кажется, вам сначала нужно проверить что та либа для создания excel-файлов умеет сохранять картинки в ячейках
Название: Re: Сохранение и открытие QTableWidget
Отправлено: Dr.robot от Январь 30, 2017, 18:07
Да ты прав xlwt может сохранять только bmp картинки но я попробовал и у меня программа зависла, а так bmp картинки вставляются: Python sheet.insert_bitmap("sym1.bmp",1,1)
работает но зависает когда делаю вот так Python sheet.insert_bitmap(currentRow, currentColumn, my_icon)
сейчас попробую с xlsxwriter
Название: Re: Сохранение и открытие QTableWidget
Отправлено: gil9red от Январь 30, 2017, 18:20
т.е. sheet.insert_bitmap("sym1.bmp",1,1) берет файл sym1.bmp, который лежит в папке с скриптом и вставляет в первую ячейку первой строки? Да ты прав xlwt может сохранять только bmp картинки но я попробовал и у меня программа зависла, а так bmp картинки вставляются: Python sheet.insert_bitmap("sym1.bmp",1,1)
работает но зависает когда делаю вот так Python sheet.insert_bitmap(currentRow, currentColumn, my_icon)
странный порядок аргументов в insert_bitmap, my_icon по идеи должна быть в первом аргументе Предлагаю следующее: получаете ячейку QTableWidgetItem, у нее берете иконку, сохраняете ее как bmp и в insert_bitmap передаете ее путь после удаляете ее, что-то вроде такого: Python icon_file_name = "cell_icon.bmp" # # Тут начало цикла для перебора ячеек # item = self.table.item(currentRow, currentColumn) # Сохранение иконки ячейки в файл img = item.data(Qt.DecorationRole) img.save(icon_file_name) sheet.insert_bitmap(icon_file_name, currentRow, currentColumn) # # Тут конец цикла для перебора ячеек # # Теперь иконку можно удалить import os if os.path.exist(icon_file_name): os.remove(icon_file_name)
Если у sheet есть метод для вставки иконки как байтового массива, то лучше им воспользоваться, чем создавать тот времененный файл иконки
Название: Re: Сохранение и открытие QTableWidget
Отправлено: Dr.robot от Январь 30, 2017, 20:55
т.е. sheet.insert_bitmap("sym1.bmp",1,1) берет файл sym1.bmp, который лежит в папке с скриптом и вставляет в первую ячейку первой строки?
Да именно так. Но почему когда я делаю вот так Python def save_file(self): filename = (QFileDialog.getSaveFileName(self, 'Сохранить', '', ".xls(*.xls)")) wbk = xlwt.Workbook() sheet = wbk.add_sheet("схема", cell_overwrite_ok=True) for currentColumn in range(self.table.columnCount()): for currentRow in range(self.table.rowCount()): my_icon = self.table.item(currentRow, currentColumn) sheet.insert_bitmap(my_icon, currentRow, currentColumn) wbk.save(filename)
Он мне выдает ошибку Traceback (most recent call last): File "C:/Users/Desktop/game_ower/troubletable.py", line 83, in save_file sheet.insert_bitmap(my_icon, currentRow, currentColumn) File "C:\Python34\lib\site-packages\xlwt\Worksheet.py", line 1122, in insert_bitmap bmp = Bitmap.ImDataBmpRecord(filename) File "C:\Python34\lib\site-packages\xlwt\Bitmap.py", line 273, in __init__ self.width, self.height, self.size, data = _process_bitmap(filename) File "C:\Python34\lib\site-packages\xlwt\Bitmap.py", line 195, in _process_bitmap with open(bitmap, "rb") as fh: TypeError: invalid file: <PyQt4.QtGui.QTableWidgetItem object at 0x0000000003AB64C8> Файла нет =( Получается я не сохраняю в ячейки QtableWWidget картинки а просто их там рисую. беда... А можно по подробнее что вы предложили а то я не совсем понял.
Название: Re: Сохранение и открытие QTableWidget
Отправлено: gil9red от Январь 31, 2017, 09:00
Вы наверное меня не читаете Вот это я предложил сделать: Python item = self.table.item(currentRow, currentColumn) # Сохранение иконки ячейки в файл img = item.data(Qt.DecorationRole) img.save(icon_file_name) sheet.insert_bitmap(icon_file_name, currentRow, currentColumn)
Вот сделали вы: Python my_icon = self.table.item(currentRow, currentColumn) sheet.insert_bitmap(my_icon, currentRow, currentColumn)
Ваш код, конечно, не будет работать ведь либа xlwt не умеет (и не должна) работать с объектами либы PyQt4
Название: Re: Сохранение и открытие QTableWidget
Отправлено: Dr.robot от Февраль 05, 2017, 18:36
То что вы предложили не работает и не подходит для моей задачи. Дело в том что я сохраняю вот это <PyQt4.QtGui.QTableWidgetItem object at 0x0000000003AB64C8> вместо картинки. Я даже тестировал и сохранял в обычный текстовой файл и получал тоже самое. Если xlwt не подходит то есть что ни будь другое? Мне даже не обязательно в табличный формат. Главное записать и считать. Помогите я уже все перепробовал. Просто ступор какой то ни кто не знает...
Название: Re: Сохранение и открытие QTableWidget
Отправлено: gil9red от Февраль 06, 2017, 08:26
Вы ошибаетесь и если приложите свой код, который после моих советов, все-равно не хочет работать, то поразбираемся А сохранять таблицу можно в XML или JSON текст ячеек просто сохранить, а их иконки сохранять как base64
И на будущее, если проблема в вопросе затягивается, то советую прикладывать минимальных проект с проблемой, тогда желающие помочь, смогут у себя его запускать и так найти причину проблемы будет намного проще, чем давать советы, основанные только на жалобе ТС
|