QSqlTableModel отображение файлов BLOB
Есть таблица в которой хранятся по мимо обычной информации также PDF документы в виде BLOB, которые отображаются вот так в виде знаков вопросов:
Как сделать эти "знаки вопросов" более дружелюбнее пользователю? (Иконку бы какую-нибудь туда засунуть или что-то еще, а то я сразу предвкушаю вопрос, от пользователя: "А что это за знаки вопросов?")
Минимальный пример (рядом с файлом кода нужно положить любой файл с названием test_BLOB.jpg, что бы было что конвертировать в BLOB):
import sys
import os
from PySide2 import QtSql
from PySide2 import QtWidgets
from PySide2 import QtCore
class Storage_app(QtWidgets.QMainWindow):
def __init__(self, parent=None) -> None:
super().__init__()
self.createConnection()
self.fillTable() # !!! тестовое заполнение базы данных
self.createModel()
self.initUI()
self.centralWidget = QtWidgets.QWidget()
self.setCentralWidget(self.centralWidget)
layout = QtWidgets.QVBoxLayout(self.centralWidget)
layout.addWidget(self.view)
if not parent:
self.show()
def createConnection(self):
self.db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
self.db.setDatabaseName("local_base.db") # !!! .db
if not self.db.open():
print("Cannot establish a database connection")
return False
def fillTable(self):
"""
Вспомогательная функция заполнениия базы данных
Отключить после тестового запуска
"""
file_path = (f"{os.getcwd()}\\test_BLOB.jpg")
test_BLOB = self.convertToBinaryData(file_path)
test_BLOB = QtCore.QByteArray(test_BLOB)
self.db.transaction()
q = QtSql.QSqlQuery()
#
q.exec_("DROP TABLE IF EXISTS company;")
q.exec_("CREATE TABLE company ("
"id INT PRIMARY KEY, "
"name_company TEXT NOT NULL, "
"blob_data BLOB NOT NULL );")
# Вставка тестовых значений
query = QtSql.QSqlQuery()
query.prepare("INSERT INTO company (id, name_company, blob_data) "
"VALUES (:id, :name_company, :blob_data)")
query.bindValue(":id", 1)
query.bindValue(":name_company", 'АО КОПЫТА')
query.bindValue(":blob_data", test_BLOB)
query.exec_()
query = QtSql.QSqlQuery()
query.prepare("INSERT INTO company (id, name_company, blob_data) "
"VALUES (:id, :name_company, :blob_data)")
query.bindValue(":id", 2)
query.bindValue(":name_company", 'АО РОГА')
query.bindValue(":blob_data", test_BLOB)
query.exec_()
self.db.commit()
def createModel(self):
"""
Создание модели для отображения
"""
self.model = QtSql.QSqlRelationalTableModel()
self.model.setTable("company")
self.model.setHeaderData(0, QtCore.Qt.Horizontal, "id")
self.model.setHeaderData(1, QtCore.Qt.Horizontal, "Наиманование")
self.model.setHeaderData(2, QtCore.Qt.Horizontal, "Документы")
self.model.select()
def initUI(self):
self.view = QtWidgets.QTableView()
self.view.setModel(self.model)
mode = QtWidgets.QAbstractItemView.SingleSelection
self.view.setSelectionMode(mode)
def closeEvent(self, event):
if (self.db.open()):
self.db.close()
def convertToBinaryData(self, file_path):
# Конвертирование в BLOB
with open(file_path, 'rb') as file:
blobData = file.read()
return blobData
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
app.setStyle('Fusion')
w = Storage_app()
app.exec_()
Ответы (1 шт):
Как говорится sorry for my terrible python (знаю его поверхностно), но надеюсь поймете..
Вам необходимо сделать кастомную модель данных, и переопределить для нужного столбца DisplayRole чтобы скрыть текст (ромбики-вопросики) и DecorationRole для вывода иконки
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
db_file = "test.db3"
def create_connection(file_path):
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName(file_path)
if not db.open():
print("Cannot establish a database connection to {}!".format(file_path))
return False
return True
def fill_tables():
q = QSqlQuery()
q.exec_("DROP TABLE IF EXISTS Manufacturers;")
q.exec_("CREATE TABLE Manufacturers (Company TEXT, Country TEXT,Blob_data BLOB NOT NULL);")
q.exec_("INSERT INTO Manufacturers VALUES ('VW', 'Germany','an blob data');")
q.exec_("INSERT INTO Manufacturers VALUES ('Honda' , 'Japan', 'another blob data');")
# Тут описываем нашу кастомную модель, основанную на qsqltablemodel
class myTableModel(QSqlTableModel):
def data(self, index, role=Qt.DisplayRole): # Переопределяем метод data
if index.column() == 2 and role == Qt.DisplayRole: # для второго столбца, скроем выводимый текст
return "";
if index.column() == 2 and role == Qt.DecorationRole: # и для него же выведем иконку в качестве декора
return QIcon.fromTheme("folder")
return QSqlTableModel.data(self,index, role) # все остальное должно штатно обработаться qsqltablemodel
if __name__ == '__main__':
app = QApplication(sys.argv)
if not create_connection(db_file):
sys.exit(-1)
fill_tables()
view = QTableView()
# Модель создаем уже свою кастомную
model = myTableModel()
model.setTable("Manufacturers")
model.select()
view.setModel(model)
view.show()
sys.exit(app.exec_())
Результат получается следующий. При этом не важно BLOB у вас или что-то другое. Переопределяя модель вы можете сделать что угодно

