Форум программистов, компьютерный форум, киберфорум
Python: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.79/34: Рейтинг темы: голосов - 34, средняя оценка - 4.79
2 / 2 / 2
Регистрация: 12.05.2016
Сообщений: 67
PyQt5

Делегат перекрашивания ячейки QTableView

20.10.2021, 14:37. Показов 7422. Ответов 24

Студворк — интернет-сервис помощи студентам
Всем привет, есть небольшой код с GUI-окном и БД (во вложении).
Окно делится на две части, в верхней части вводится информация которую необходимо добавить в БД (отображение снизу).
Информация добавляется через кнопку Добавить.

Пы.Сы.
Я пытаюсь добавить делегаты к QTableView, У меня получилось добавить делегат, который центрирует текст в ячейках,
но у меня никак не получается "сварганить" делегат, который бы в столбце "На контроле" при значении столбца "1" перекрашивал бы ячейку столбца в красный цвет.

Пы.Сы.Пы.Сы.
1.архив распаковать в папку (в архиве бд + gui + скрипт).
2.запускать main.py

Пы.Сы.Пы.Сы.Пы.Сы
В коде есть работающая строка поиска, кнопки Добавить и Удалить добавляют и удаляют строки в исходную модель, но такое не прокатывает с отфильтрованной моделью, как реализовать добавление/удаление строк в отфильтрованной модели? (QSortFilterProxyModel).

Дублирую основной код:
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
from mainWindow import Ui_MainWindow #основное GUI-окно
#import reestr_pb #реестр PB второе окно
from PyQt5 import QtCore, QtGui, QtWidgets, Qt
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QMessageBox #интерфейс
from PyQt5.QtSql import QSqlDatabase, QSqlTableModel, QSqlQueryModel
 
#import configparser #библиотека для чтения настроек из файла settings.ini
import sys
 
class MainApp(QMainWindow, Ui_MainWindow): #основной класс главного окна
    def __init__(self, parent=None):
        super(MainApp,self).__init__(parent)
        self.setupUi(self) #иницилизация главного окна
        self.Init_Ui() #инициализация привязок к кнопкам главного окна
  
    def Init_Ui(self): #привязка функций к кнопкам
        self.CreateConnection()
        self.CreateModel()
        #self.reestr.clicked.connect(self.openReestr)  # Кнопка открытия реестра
        self.StatusPB.clicked.connect(self.addRecord)
        self.DelPB.clicked.connect(self.delRecord)
 
        # строка поиска
        self.filter_proxy_model = QtCore.QSortFilterProxyModel()
        self.filter_proxy_model.setSourceModel(self.model)
        self.filter_proxy_model.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.filter_proxy_model.setFilterKeyColumn(2)
        search_field = self.search
        search_field.textChanged.connect(self.filter_proxy_model.setFilterRegExp)
        self.MainReestr.setModel(self.filter_proxy_model)  # привязка отфильтрованной модели к таблице
        self.MainReestr.resizeColumnsToContents()  # ресайз размера колонок по содержимому
        self.MainReestr.hideColumn(0)  # Скрываем столбец с ID
        #центрирование содержимого столбцов в таблице
        delegate = AlignDelegate(self.MainReestr)
        for x in range(12):
            self.MainReestr.setItemDelegateForColumn(x, delegate)
 
 
    def addRecord(self): #добавление в неотфильтрованную модель
        record = self.model.record()
        record.setValue(1, self.untb.text())
        record.setValue(2, self.fio.text())
        record.setValue(3, str(self.birthdate.date().toPyDate()))
        record.setValue(4, self.dul.text())
        record.setValue(6, self.newStatusPB.text())
        record.setValue(7, self.inoBank.text())
        record.setValue(8, self.oes.text())
        record.setValue(9, self.control.text())
        record.setValue(10, self.sanction.text())
        record.setValue(11, self.comment.text())
        self.model.insertRecord(-1, record)
        self.model.select()
 
 
    def delRecord(self, MainReestr): #удаление из неотфильтрованной модели
        index = self.MainReestr.currentIndex()
        if not index.isValid():
            return
        record = self.model.record(index.row())
        self.model.removeRow(index.row())
        self.model.submitAll()
        self.model.select()
 
    #def openReestr(self):
    #    self.operR = reestrWidget()
    #    self.operR.show()
 
    def CreateConnection(self):
        con = QSqlDatabase.addDatabase("QSQLITE")
        con.setDatabaseName("clients.db")
        if not con.open():
            QMessageBox.critical(None,"QTableView Example - Error!", "Database Error: %s" % con.lastError().databasetext(),)
            return False
        return True
 
    def CreateModel(self):
        self.model = QSqlTableModel(self)
        self.model.setTable('mainReestr')
        self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
        self.model.setHeaderData(1, QtCore.Qt.Horizontal, 'УНТБ')
        self.model.setHeaderData(2, QtCore.Qt.Horizontal, 'ФИО')
        self.model.setHeaderData(3, QtCore.Qt.Horizontal, 'Дата рождения')
        self.model.setHeaderData(4, QtCore.Qt.Horizontal, 'ДУЛ')
        self.model.setHeaderData(5, QtCore.Qt.Horizontal, 'Статус')
        self.model.setHeaderData(6, QtCore.Qt.Horizontal, 'Присвоение статуса')
        self.model.setHeaderData(7, QtCore.Qt.Horizontal, 'Запрос инобанка')
        self.model.setHeaderData(8, QtCore.Qt.Horizontal, 'Отказ')
        self.model.setHeaderData(9, QtCore.Qt.Horizontal, 'На контроле')
        self.model.setHeaderData(10, QtCore.Qt.Horizontal, 'Санкции')
        self.model.setHeaderData(11, QtCore.Qt.Horizontal, 'Комментарий')
        self.model.select()
 
class AlignDelegate(QtWidgets.QStyledItemDelegate): #делегат центрирования содержимого в столбцах
    def initStyleOption(self, option, index):
        super(AlignDelegate, self).initStyleOption(option, index)
        option.displayAlignment = QtCore.Qt.AlignCenter
 
if __name__ == '__main__':
    app = QApplication(sys.argv) #новый экземпляр класса QApplication
    window = MainApp()  #объект класса MainApp
    window.show() #запускаем окно
    app.exec_() #запускаем приложение
Вложения
Тип файла: rar example.rar (4.6 Кб, 17 просмотров)
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
20.10.2021, 14:37
Ответы с готовыми решениями:

Делегат перекрашивания строки по условию в столбце QTableView
Всем привет. У меня есть вот такой делегат, который по условию в колонке перекрашивает ячейку 26 или 27 колонки в красный цвет. ...

Удалить делегат из QTableView
Добрый день! Как удалить делегат из QTableView? Нашел в теме то что нужно: view->setItemDelegateForColumn(2, NULL); Как...

Делегат QCheckBox в QTableView
Всем привет. Написал делегат: class FlagDelegate (QtWidgets.QStyledItemDelegate): def createEditor (self, parent, options,...

24
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
20.10.2021, 16:23
Делегат стоит использовать, если надо нарисовать в ячейке что-то уж очень нестандартное.
Для более простых вещей используйте метод data() с нужным QtRole.
https://doc.qt.io/qt-5/qt.html#ItemDataRole-enum
Qt::TextAlignmentRole 7 The alignment of the text for items rendered with the default delegate. (Qt::Alignment)
Qt::BackgroundRole 8 The background brush used for items rendered with the default delegate. (QBrush)
1
2 / 2 / 2
Регистрация: 12.05.2016
Сообщений: 67
20.10.2021, 17:26  [ТС]
Как прикрутить метод data() к моей модели? (def CreateModel...) . Про роли и QBrush читал, только не понял как их использовать вместе с моделью QSqlTableModel.

Добавлено через 15 минут
Предполагаю, что я модель неправильно создал, может надо было наследоваться от QAbstractTableModel?
0
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
20.10.2021, 18:06
Лучший ответ Сообщение было отмечено T4gr0id как решение

Решение

А вот, делайте по аналогии QSqlTableModel отображение файлов BLOB в таблице .
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
20.10.2021, 19:28
T4gr0id, вот простой пример делегата
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
class Delegate(QItemDelegate):
    def __init__(self):
        super().__init__()
        self.filter = ''
 
    def paint(self,painter,option,index):
        row, col, txt = index.row(), index.column(), index.data()
        if self.filter and self.filter in txt:
            painter.setBrush(QBrush(Qt.yellow))
            painter.drawRect(option.rect)     
        self.drawDisplay(painter,option,option.rect,txt)
 
 
class View(QTableView):
    def __init__(self):
        super().__init__()
        self.model = QStandardItemModel()
        self.setSelectionMode(1)
        for row in range(5):
            for col in range(5):
                tmp = str(randint(10000,20000))
                item = QStandardItem(tmp)
                self.model.setItem(row,col,item)
        self.setModel(self.model)
        d = Delegate()
        self.setItemDelegate(d)
        d.filter = '8'
Добавлено через 2 минуты
можете использовать QSqlTableModel без всяких изврашений костылей
1
 Аватар для kapbepucm
1566 / 739 / 321
Регистрация: 02.05.2020
Сообщений: 1,656
21.10.2021, 16:01
Лучший ответ Сообщение было отмечено T4gr0id как решение

Решение

Пример, в котором центруем ячеки второго столбика и красим фон в красный цвет если их значение будет 1:
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
import sys
from PyQt5.QtWidgets import QApplication, QTableView
from PyQt5.QtSql     import QSqlDatabase, QSqlQuery, QSqlTableModel
from PyQt5.QtCore    import Qt
from PyQt5.QtGui     import QBrush
 
class Model(QSqlTableModel):
  def data(self, index, role = Qt.DisplayRole):
    if index.column() == 1:
      if role == Qt.TextAlignmentRole:
        return Qt.AlignHCenter | Qt.AlignVCenter
      if role == Qt.BackgroundRole:
        if super().data(index) == 1:
          return QBrush(Qt.red)
    return super().data(index, role)
 
class Window(QTableView):
  def __init__(self):
    super().__init__(None)
    model = Model()
    model.setTable("t1")
    model.select()
    self.setModel(model)
 
app = QApplication(sys.argv)
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName(":memory:")
db.open()
query = QSqlQuery(db)
query.exec_("CREATE TABLE t1 (id INTEGER PRIMARY KEY, value INTEGER);")
query.exec_("INSERT INTO t1 (id, value) VALUES (0, 1);")
query.exec_("INSERT INTO t1 (id, value) VALUES (1, 1);")
query.exec_("INSERT INTO t1 (id, value) VALUES (2, 1);")
window = Window()
window.show()
sys.exit(app.exec_())
1
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
21.10.2021, 16:33
kapbepucm, можно и так, минус в том, что гибкость теряется. у делегата можно условие поменять на лету не трогая данных, а модель на лету переделывать как-то не фонтан.
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
from PyQt5.QtWidgets import (QWidget, QGridLayout,QListView,QTableView, QItemDelegate,
QApplication,QLineEdit,QPushButton)
from PyQt5.QtGui import QStandardItemModel,QStandardItem, QBrush,QPen,QFont
from PyQt5.QtCore import Qt
from random import randint
 
class Delegate(QItemDelegate):
    def __init__(self):
        super().__init__()
        self._filter = ''
        
    def check(self,txt):
        if self._filter and self._filter in txt: 
            return True
        return False
 
    def paint(self,painter,option,index):
        _data = index.data()
        if self.check(_data):
            painter.setBrush(Qt.yellow)
            painter.setPen(Qt.NoPen)
            painter.drawRect(option.rect)
        self.drawDisplay(painter,option,option.rect,_data)
 
class View(QTableView):
    def __init__(self):
        super().__init__()
        self.model = QStandardItemModel(5,5)
        for row in range(5):
            for col in range(5):
                tmp = str(randint(10000,20000))
                item = QStandardItem(tmp)
                self.model.setItem(row,col,item)
        self.setModel(self.model)
        d = Delegate()
        self.setItemDelegate(d)
        d.filter = '8'
 
class W(QWidget):
    def __init__(self):
        super().__init__()
        grid = QGridLayout(self)
        self.view = View()
        btn = QPushButton('Reload')
        grid.addWidget(self.view)
        grid.addWidget(btn)
        btn.clicked.connect(self.on_reload)
        
    def on_reload(self):
        r = str(randint(2,20))
        print(r)
        self.view.itemDelegate()._filter = r
        self.view.viewport().update()
        
    
        
 
if __name__ == "__main__":
    app = QApplication([])
    w = W()
    w.show()
    app.exec_()
0
2 / 2 / 2
Регистрация: 12.05.2016
Сообщений: 67
21.10.2021, 16:54  [ТС]
Вот в таком виде сделал - получилось! Еще вопрос....можно ли добавлять/удалять строки из отсортированной модели?QSortFilterProxyModel (см.выше).

Python
1
2
3
4
5
6
7
8
9
class DelegateFromModel(PyQt5.QtSql.QSqlTableModel):
    def data(self, item, role):
        if role == QtCore.Qt.BackgroundRole: #перекрашивание определенного столбца по условию (Если в ячейке True)
            if item.column() == 9 and QSqlQueryModel.data(self, self.index(item.row(), 9), QtCore.Qt.DisplayRole) == True:
                return QtGui.QColor.fromRgb(60,179,227)
        if role == QtCore.Qt.DisplayRole: #возвращает вместо 1 и 0 в ячейках True и False
            if item.column() == 9:
                return True if QSqlQueryModel.data(self, item, QtCore.Qt.DisplayRole) == 1 else False
        return QSqlQueryModel.data(self, item, role)
Добавлено через 9 минут
Пы.Сы. после того как я меняю вручную значение в ячейке с 0 на 1 у меня False на True меняется не сразу, а только после, например, добавления строки - в данной функции есть строка model.select()
для того чтобы обновить ячейку обязательно делать model.select() или есть другие варианты?
0
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
21.10.2021, 17:07
T4gr0id, сортировкой занимается прокси-модель, а из прокси вы ничего не удаляете, только из исходной.
Цитата Сообщение от T4gr0id Посмотреть сообщение
для того чтобы обновить ячейку обязательно делать model.select() или есть другие варианты?
Там надо вызвать что-то типа reset(), уже точно не помню.
0
2 / 2 / 2
Регистрация: 12.05.2016
Сообщений: 67
21.10.2021, 23:36  [ТС]
Выражаю благодарность dondublon, vic5710, kapbepucm!
Я несколько дней копал интернет в поисках инфы, а Вы мне за вечер накидали много полезной годноты
В ближайшее время опубликую тут измененный код.
0
 Аватар для kapbepucm
1566 / 739 / 321
Регистрация: 02.05.2020
Сообщений: 1,656
22.10.2021, 09:50
Цитата Сообщение от T4gr0id Посмотреть сообщение
для того чтобы обновить ячейку обязательно делать model.select() или есть другие варианты?
Модель может подавать вьюхе специальный сигнал "данные такой то ячейки изменены", и вьюха обновляет только 1 ячейку.
А в случае model.select() вьюха будет перерисовываться полностью.
0
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
22.10.2021, 09:58
T4gr0id, ну ты заходи, если что...
0
2 / 2 / 2
Регистрация: 12.05.2016
Сообщений: 67
23.10.2021, 08:25  [ТС]
Как сигнал называется?
0
 Аватар для kapbepucm
1566 / 739 / 321
Регистрация: 02.05.2020
Сообщений: 1,656
25.10.2021, 13:28
Цитата Сообщение от T4gr0id Посмотреть сообщение
Как сигнал называется?
QAbstractItemModel::dataChanged

Цитата Сообщение от T4gr0id Посмотреть сообщение
после того как я меняю вручную значение в ячейке с 0 на 1 у меня False на True меняется не сразу
что подразумевается под ручным изменением?
0
2 / 2 / 2
Регистрация: 12.05.2016
Сообщений: 67
25.10.2021, 22:19  [ТС]
Встаю в ячейку и меняю содержимое с 0 на 1
0
 Аватар для kapbepucm
1566 / 739 / 321
Регистрация: 02.05.2020
Сообщений: 1,656
26.10.2021, 08:33
Цитата Сообщение от T4gr0id Посмотреть сообщение
Встаю в ячейку и меняю содержимое с 0 на 1
И если убрать после этого курсор на другую ячейку, то она отображает прежнее 0 (False), и при вызове model.select() магическим образом меняет на 1 (True)?
0
2 / 2 / 2
Регистрация: 12.05.2016
Сообщений: 67
26.10.2021, 22:39  [ТС]
совершенно верно))
0
 Аватар для kapbepucm
1566 / 739 / 321
Регистрация: 02.05.2020
Сообщений: 1,656
27.10.2021, 08:19
Не получается воспроизвести такое поведение. Приведите минимальный пример, чтоли
0
2 / 2 / 2
Регистрация: 12.05.2016
Сообщений: 67
27.10.2021, 14:25  [ТС]
В первом сообщении есть архив, если вы его запустите. Там будет как раз такое поведение ячеек.
0
 Аватар для kapbepucm
1566 / 739 / 321
Регистрация: 02.05.2020
Сообщений: 1,656
27.10.2021, 16:04
Цитата Сообщение от T4gr0id Посмотреть сообщение
В первом сообщении есть архив, если вы его запустите. Там будет как раз такое поведение ячеек.
Собрал ваш архив в один файл:
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
from PyQt5 import QtCore, QtGui, QtWidgets, Qt
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QMessageBox #интерфейс
from PyQt5.QtSql import QSqlDatabase, QSqlTableModel, QSqlQueryModel, QSqlQuery
import sys
 
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1097, 884)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setGeometry(QtCore.QRect(10, 10, 1081, 71))
        self.groupBox.setObjectName("groupBox")
        self.reestr = QtWidgets.QToolButton(self.groupBox)
        self.reestr.setGeometry(QtCore.QRect(10, 20, 91, 35))
        self.reestr.setObjectName("reestr")
        self.load_reestr = QtWidgets.QToolButton(self.groupBox)
        self.load_reestr.setGeometry(QtCore.QRect(120, 20, 91, 35))
        self.load_reestr.setObjectName("load_reestr")
        self.operations_59 = QtWidgets.QToolButton(self.groupBox)
        self.operations_59.setGeometry(QtCore.QRect(230, 20, 91, 35))
        self.operations_59.setObjectName("operations_59")
        self.operations = QtWidgets.QToolButton(self.groupBox)
        self.operations.setGeometry(QtCore.QRect(340, 20, 91, 35))
        self.operations.setObjectName("operations")
        self.help = QtWidgets.QToolButton(self.groupBox)
        self.help.setGeometry(QtCore.QRect(450, 20, 91, 35))
        self.help.setObjectName("help")
        self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_2.setGeometry(QtCore.QRect(10, 90, 1071, 211))
        self.groupBox_2.setObjectName("groupBox_2")
        self.label = QtWidgets.QLabel(self.groupBox_2)
        self.label.setGeometry(QtCore.QRect(150, 30, 31, 20))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.groupBox_2)
        self.label_2.setGeometry(QtCore.QRect(20, 30, 31, 20))
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self.groupBox_2)
        self.label_3.setGeometry(QtCore.QRect(900, 30, 47, 20))
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(self.groupBox_2)
        self.label_4.setGeometry(QtCore.QRect(520, 30, 91, 20))
        self.label_4.setObjectName("label_4")
        self.label_5 = QtWidgets.QLabel(self.groupBox_2)
        self.label_5.setGeometry(QtCore.QRect(740, 30, 31, 20))
        self.label_5.setObjectName("label_5")
        self.untb = QtWidgets.QLineEdit(self.groupBox_2)
        self.untb.setGeometry(QtCore.QRect(60, 30, 81, 20))
        self.untb.setObjectName("untb")
        self.fio = QtWidgets.QLineEdit(self.groupBox_2)
        self.fio.setGeometry(QtCore.QRect(180, 30, 321, 20))
        self.fio.setObjectName("fio")
        self.dul = QtWidgets.QLineEdit(self.groupBox_2)
        self.dul.setGeometry(QtCore.QRect(770, 30, 113, 20))
        self.dul.setObjectName("dul")
        self.birthdate = QtWidgets.QDateEdit(self.groupBox_2)
        self.birthdate.setGeometry(QtCore.QRect(610, 30, 110, 22))
        self.birthdate.setObjectName("birthdate")
        self.label_6 = QtWidgets.QLabel(self.groupBox_2)
        self.label_6.setGeometry(QtCore.QRect(20, 60, 111, 20))
        self.label_6.setObjectName("label_6")
        self.newStatusPB = QtWidgets.QLineEdit(self.groupBox_2)
        self.newStatusPB.setGeometry(QtCore.QRect(130, 60, 40, 20))
        self.newStatusPB.setObjectName("newStatusPB")
        self.label_7 = QtWidgets.QLabel(self.groupBox_2)
        self.label_7.setGeometry(QtCore.QRect(330, 60, 161, 20))
        self.label_7.setObjectName("label_7")
        self.oes = QtWidgets.QLineEdit(self.groupBox_2)
        self.oes.setGeometry(QtCore.QRect(500, 60, 40, 20))
        self.oes.setObjectName("oes")
        self.label_8 = QtWidgets.QLabel(self.groupBox_2)
        self.label_8.setGeometry(QtCore.QRect(180, 60, 91, 20))
        self.label_8.setObjectName("label_8")
        self.inoBank = QtWidgets.QLineEdit(self.groupBox_2)
        self.inoBank.setGeometry(QtCore.QRect(280, 60, 40, 20))
        self.inoBank.setObjectName("inoBank")
        self.control = QtWidgets.QLineEdit(self.groupBox_2)
        self.control.setGeometry(QtCore.QRect(630, 60, 40, 20))
        self.control.setObjectName("control")
        self.label_9 = QtWidgets.QLabel(self.groupBox_2)
        self.label_9.setGeometry(QtCore.QRect(560, 60, 71, 20))
        self.label_9.setObjectName("label_9")
        self.sanction = QtWidgets.QLineEdit(self.groupBox_2)
        self.sanction.setGeometry(QtCore.QRect(730, 60, 40, 20))
        self.sanction.setObjectName("sanction")
        self.label_10 = QtWidgets.QLabel(self.groupBox_2)
        self.label_10.setGeometry(QtCore.QRect(680, 60, 51, 20))
        self.label_10.setObjectName("label_10")
        self.groupBox_3 = QtWidgets.QGroupBox(self.groupBox_2)
        self.groupBox_3.setGeometry(QtCore.QRect(20, 90, 1041, 111))
        self.groupBox_3.setObjectName("groupBox_3")
        self.comment = QtWidgets.QLineEdit(self.groupBox_3)
        self.comment.setGeometry(QtCore.QRect(10, 20, 1021, 81))
        self.comment.setObjectName("comment")
        self.groupBox_4 = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_4.setGeometry(QtCore.QRect(10, 390, 1081, 471))
        self.groupBox_4.setObjectName("groupBox_4")
        self.MainReestr = QtWidgets.QTableView(self.groupBox_4)
        self.MainReestr.setGeometry(QtCore.QRect(10, 20, 1061, 441))
        self.MainReestr.setObjectName("MainReestr")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setGeometry(QtCore.QRect(10, 310, 1081, 80))
        self.tabWidget.setObjectName("tabWidget")
        self.tab_1 = QtWidgets.QWidget()
        self.tab_1.setObjectName("tab_1")
        self.StatusPB = QtWidgets.QToolButton(self.tab_1)
        self.StatusPB.setGeometry(QtCore.QRect(10, 10, 110, 35))
        self.StatusPB.setObjectName("StatusPB")
        self.DelPB = QtWidgets.QToolButton(self.tab_1)
        self.DelPB.setGeometry(QtCore.QRect(130, 10, 110, 35))
        self.DelPB.setObjectName("DelPB")
        self.RefreshPB = QtWidgets.QToolButton(self.tab_1)
        self.RefreshPB.setGeometry(QtCore.QRect(250, 10, 110, 35))
        self.RefreshPB.setObjectName("RefreshPB")
        self.search = QtWidgets.QLineEdit(self.tab_1)
        self.search.setGeometry(QtCore.QRect(370, 10, 411, 31))
        self.search.setObjectName("search")
        self.tabWidget.addTab(self.tab_1, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.tabWidget.addTab(self.tab_2, "")
        self.tab_3 = QtWidgets.QWidget()
        self.tab_3.setObjectName("tab_3")
        self.tabWidget.addTab(self.tab_3, "")
        self.tab_4 = QtWidgets.QWidget()
        self.tab_4.setObjectName("tab_4")
        self.tabWidget.addTab(self.tab_4, "")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
 
        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
 
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.groupBox.setTitle(_translate("MainWindow", "Панель инструментов:"))
        self.reestr.setText(_translate("MainWindow", "reestr"))
        self.load_reestr.setText(_translate("MainWindow", "load reestr"))
        self.operations_59.setText(_translate("MainWindow", "operations_59"))
        self.operations.setText(_translate("MainWindow", "operations"))
        self.help.setText(_translate("MainWindow", "help"))
        self.groupBox_2.setTitle(_translate("MainWindow", "Сведения из реестра:"))
        self.label.setText(_translate("MainWindow", "ФИО:"))
        self.label_2.setText(_translate("MainWindow", "УНТБ:"))
        self.label_3.setText(_translate("MainWindow", "Статус:"))
        self.label_4.setText(_translate("MainWindow", "Дата рождения:"))
        self.label_5.setText(_translate("MainWindow", "ДУЛ:"))
        self.label_6.setText(_translate("MainWindow", "Присвоение статуса:"))
        self.label_7.setText(_translate("MainWindow", "Отказ в совершении операции:"))
        self.label_8.setText(_translate("MainWindow", "Запрос инобанка:"))
        self.label_9.setText(_translate("MainWindow", "На контроле:"))
        self.label_10.setText(_translate("MainWindow", "Санкции:"))
        self.groupBox_3.setTitle(_translate("MainWindow", "Комментарий:"))
        self.groupBox_4.setTitle(_translate("MainWindow", "Основной реестр:"))
        self.StatusPB.setText(_translate("MainWindow", "Добавить клиента"))
        self.DelPB.setText(_translate("MainWindow", "Удалить строку"))
        self.RefreshPB.setText(_translate("MainWindow", "Обновить таблицу"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_1), _translate("MainWindow", "Работа с таблицей"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Присвоение статуса"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "Инобанк"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _translate("MainWindow", "Отказ"))
 
class MainApp(QMainWindow, Ui_MainWindow): #основной класс главного окна
    def __init__(self, parent=None):
        super(MainApp,self).__init__(parent)
        self.setupUi(self) #иницилизация главного окна
  
        self.CreateConnection()
        self.CreateModel()
        #self.reestr.clicked.connect(self.openReestr)  # Кнопка открытия реестра
        self.StatusPB.clicked.connect(self.addRecord)
        self.DelPB.clicked.connect(self.delRecord)
 
        # строка поиска
        self.filter_proxy_model = QtCore.QSortFilterProxyModel()
        self.filter_proxy_model.setSourceModel(self.model)
        self.filter_proxy_model.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.filter_proxy_model.setFilterKeyColumn(2)
        search_field = self.search
        search_field.textChanged.connect(self.filter_proxy_model.setFilterRegExp)
        self.MainReestr.setModel(self.filter_proxy_model)  # привязка отфильтрованной модели к таблице
        self.MainReestr.resizeColumnsToContents()  # ресайз размера колонок по содержимому
        self.MainReestr.hideColumn(0)  # Скрываем столбец с ID
        #центрирование содержимого столбцов в таблице
        delegate = AlignDelegate(self.MainReestr)
        for x in range(12):
            self.MainReestr.setItemDelegateForColumn(x, delegate)
 
    def addRecord(self): #добавление в неотфильтрованную модель
        record = self.model.record()
        record.setValue(1, self.untb.text())
        record.setValue(2, self.fio.text())
        record.setValue(3, str(self.birthdate.date().toPyDate()))
        record.setValue(4, self.dul.text())
        record.setValue(6, self.newStatusPB.text())
        record.setValue(7, self.inoBank.text())
        record.setValue(8, self.oes.text())
        record.setValue(9, self.control.text())
        record.setValue(10, self.sanction.text())
        record.setValue(11, self.comment.text())
        self.model.insertRecord(-1, record)
        self.model.select()
 
    def delRecord(self, MainReestr): #удаление из неотфильтрованной модели
        index = self.MainReestr.currentIndex()
        if not index.isValid():
            return
        record = self.model.record(index.row())
        self.model.removeRow(index.row())
        self.model.submitAll()
        self.model.select()
 
    def CreateConnection(self):
        con = QSqlDatabase.addDatabase("QSQLITE")
        con.setDatabaseName(":memory:")
        con.open()
        query = QSqlQuery(con)
        query.exec_("CREATE TABLE mainReestr("
                    "id INTEGER PRIMARY KEY,"
                    "untb TEXT,"
                    "fio  TEXT,"
                    "birthdate TEXT,"
                    "dul TEXT,"
                    "status TEXT,"
                    "newStatus INTEGER,"
                    "inBank INTEGER,"
                    "oes INTEGER,"
                    "control INTEGER,"
                    "sanction INTEGER,"
                    "comment TEXT);")
        query.exec_("INSERT INTO mainReestr (id) VALUES (0);")
 
    def CreateModel(self):
        self.model = QSqlTableModel(self)
        self.model.setTable('mainReestr')
        self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
        self.model.setHeaderData(1, QtCore.Qt.Horizontal, 'УНТБ')
        self.model.setHeaderData(2, QtCore.Qt.Horizontal, 'ФИО')
        self.model.setHeaderData(3, QtCore.Qt.Horizontal, 'Дата рождения')
        self.model.setHeaderData(4, QtCore.Qt.Horizontal, 'ДУЛ')
        self.model.setHeaderData(5, QtCore.Qt.Horizontal, 'Статус')
        self.model.setHeaderData(6, QtCore.Qt.Horizontal, 'Присвоение статуса')
        self.model.setHeaderData(7, QtCore.Qt.Horizontal, 'Запрос инобанка')
        self.model.setHeaderData(8, QtCore.Qt.Horizontal, 'Отказ')
        self.model.setHeaderData(9, QtCore.Qt.Horizontal, 'На контроле')
        self.model.setHeaderData(10, QtCore.Qt.Horizontal, 'Санкции')
        self.model.setHeaderData(11, QtCore.Qt.Horizontal, 'Комментарий')
        self.model.select()
 
class AlignDelegate(QtWidgets.QStyledItemDelegate): #делегат центрирования содержимого в столбцах
    def initStyleOption(self, option, index):
        super(AlignDelegate, self).initStyleOption(option, index)
        option.displayAlignment = QtCore.Qt.AlignCenter
 
if __name__ == '__main__':
    app = QApplication(sys.argv) #новый экземпляр класса QApplication
    window = MainApp()  #объект класса MainApp
    window.show() #запускаем окно
    app.exec_() #запускаем приложение
Запустил. Что-куда дальше тыкать?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
27.10.2021, 16:04
Помогаю со студенческими работами здесь

Делегат отображения даты и суммы из таблицы sqlite3 в QTableView
Всем привет. Помогите разобраться с проблемой, которую я не осилил - перерыл интернет, но так и не нашел подходящего решения. 1. Есть...

QTableView + делегат
Доброго времени суток. Придумал тут одну идею, но опыта в таких делах очень мало. Есть таблица, с одним столбцом. В котором перечислены...

QTableView удалить делегат
Здравствуйте, подскажите, как удалить делегат с таблицы? dataTable = new UsersTable(this); view = new QTableView (this); ...

Делегат QComboBox в модели QTableView
Добрый день товарищи. Появилась проблема которую не могу решить уже очень долгое время. В общем, у меня есть модель QTableView в которой я...

Не работает делегат для QTableview
Всем привет Помогите, пожалуйста, целый день сижу, мозг кипит :wall: Делаю по образцу "Star Delegate Example" Только вот...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru