Форум программистов, компьютерный форум, киберфорум
Python: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
 Аватар для Михалыч
1011 / 355 / 59
Регистрация: 28.02.2013
Сообщений: 937

QSqlTableModel отображение файлов BLOB в таблице

08.09.2021, 09:23. Показов 2253. Ответов 12

Студворк — интернет-сервис помощи студентам
Добрый день, возник вопрос: есть таблица в которой хранятся по мимо обычной информации также PDF документы в виде BLOB, которые отображаются вот так в виде знаков вопросов. Как сделать эти "знаки вопросов" более дружелюбнее пользователю? (Иконку бы какую-нибудь туда засунуть или что-то еще, а то я сразу предвкушаю вопрос, от пользователя: "А что это за знаки вопросов?").

Минимальный пример (рядом с файлом кода нужно положить любой файл с названием test_BLOB.jpg, что бы было что конвертировать в BLOB):

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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_()
Миниатюры
QSqlTableModel отображение файлов BLOB в таблице  
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
08.09.2021, 09:23
Ответы с готовыми решениями:

QSqlTableModel отображение кириллицы
Что мне сделать чтобы отображалась кириллица в TableView? Данные берутся из QSqlTableModel которая подключена к MySQL. Пробовал указывать...

Отображение QSqlTableModel в QTableView
Всем привет. Знатоки, поделитесь опытом) Есть такая ф-я, которая отображает в QTableView объект QSqlTableModel. В этом QTableView ...

Отображение BLOB из БД
День добрый! Не получается отобразить BLOB, сохраненные в БД. Страница отображает красный Х вместо картинки! Подскажите в чем...

12
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
08.09.2021, 09:28
Цитата Сообщение от Михалыч Посмотреть сообщение
(Иконку бы какую-нибудь туда засунуть
Ну иконку туда засунуть можно общим способом для иконок, без привязки именно к pdf. Или вы thumbnail хотите?
1
 Аватар для Михалыч
1011 / 355 / 59
Регистрация: 28.02.2013
Сообщений: 937
08.09.2021, 09:38  [ТС]
Цитата Сообщение от dondublon Посмотреть сообщение
Или вы thumbnail хотите?
Нет, без всяких предпросмотров, просто что бы этих знаков вопросов не было. Фантазия с помощью paint примерно такая
Миниатюры
QSqlTableModel отображение файлов BLOB в таблице  
0
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
08.09.2021, 10:01
Я работал с Qt давно, и с абстрактными моделями. Для них в методе data() https://doc.qt.io/qt-5/qabstra... .html#data на DisplayRole надо было вернуть иконку. Вам надо как-то засунуть это дело в вашу Sql model. Либо перейти к абстрактной, тоже неплохо.

Добавлено через 3 минуты
А, ну всё просто. Наследуетесь от QSqlRelationalTableModel и переопределяеете data():


C++
1
2
3
4
5
6
7
8
9
10
11
 
QVariant RelationalTableModelWithIcon::data(const QModelIndex &index, int role) const
{
if(index.column() == 3){
        if(role == Qt::DisplayRole)
            return "";
        else if ( role == Qt::DecorationRole)
            return icon;
    }
    return QSqlRelationalTableModel::data(index, role);
}
Пример с другого форума.
1
Модератор
Эксперт Python
 Аватар для Fudthhh
2695 / 1601 / 513
Регистрация: 21.02.2017
Сообщений: 4,210
Записей в блоге: 1
08.09.2021, 10:27
dondublon, Могу единственное что добавить это с помощью Qt.EditRole возвращать содержимое файла.
1
 Аватар для Михалыч
1011 / 355 / 59
Регистрация: 28.02.2013
Сообщений: 937
08.09.2021, 13:07  [ТС]
Ответ (для себя на память):

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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_())
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,764
08.09.2021, 16:01
Михалыч, тут довольно неплохо рассмотрены основы model/view/controller. иконку можно сделать через модель, можно через делегата во вьюхе, чтобы не дергать модель лишний раз
1
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
08.09.2021, 18:07
vic5710, насколько я помню, делегаты - для очень уж нестандартных вещей. Не стоит.
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,764
08.09.2021, 21:39
Цитата Сообщение от dondublon Посмотреть сообщение
для очень уж нестандартных вещей. Не стоит.
ну вот простенький пример ничего экстремального
https://blog.altuninvv.ru/прог... в-виджетах
0
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
09.09.2021, 11:09
vic5710, там переопределяют метод paint - то есть это для совсем уж ручного рисования.
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,764
09.09.2021, 12:44
Цитата Сообщение от dondublon Посмотреть сообщение
там переопределяют метод paint
стандартный метод. я использовал а поиске - к примеру если 10 < value < 100 ячейка окрашивается красным

Добавлено через 4 минуты
https://doc.qt.io/qtforpython-... ample.html
вот прям классика

Добавлено через 1 минуту
https://github.com/baoboa/pyqt... elegate.py
0
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
09.09.2021, 13:30
Цитата Сообщение от vic5710 Посмотреть сообщение
Добавлено через 4 минуты
https://doc.qt.io/qtforpython-... ample.html
вот прям классика
Там рисуют звёздочки. Проще их не нарисуешь, поэтому там использование делегата оправдано.
А вот тут -
Цитата Сообщение от vic5710 Посмотреть сообщение
ячейка окрашивается красным
- нет. Потому что нужный фон можно сделать с помощью data() c BackgroundRole.
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,764
09.09.2021, 16:32
Цитата Сообщение от dondublon Посмотреть сообщение
Потому что нужный фон можно сделать с помощью data() c BackgroundRole.
можно, дело вкуса. делал и так и так. по моим наблюдениям при больших таблицах делегат шустрее работает
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.09.2021, 16:32
Помогаю со студенческими работами здесь

Отображение Blob на форме!
Привет ребят) Сделал табличку в скл из 3 полей Id INT, pdf VARBINARY(MAX), Text VARCHAR В Делфи вставляю туда строку, то бишь...

Работа с Blob-полями в таблице
Есть БД (Paradox) и таблица В ней есть типа OLE (насколько я понимаю, это и есть Blob-поле) хочу сохранить туда файл делаю следующее:...

Просмотр blob поля в cds таблице
data.cds - данные с профилометра – в blob поле bData содержится массив 3…6 тыс. чисел (сигнал от иглы щупа) – профиль поверхности. Есть...

Работа с Blob-полями в таблице (на Delphi)
Есть БД (Paradox) и таблица В ней есть полк типа OLE (насколько я понимаю, это и есть Blob-поле) хочу сохранить туда файл делаю...

phpmyadmin отображение text как blob
Phpmyadmin отображает text как blob, varchar как binary на скриншоте surname, name - text, phone и password - varchar


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru