С Новым годом! Форум программистов, компьютерный форум, киберфорум
Python: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.58/141: Рейтинг темы: голосов - 141, средняя оценка - 4.58
 Аватар для Simply me
244 / 37 / 8
Регистрация: 05.05.2012
Сообщений: 521

Pyqt. Класс QTableView

23.12.2018, 18:01. Показов 29592. Ответов 60
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!

Напишите, пожалуйста, примеры использования QTableview: указание количества строк/столбцов, заголовки столбцов, заполнение значениями. Вроде надо с помощью QAbstractItemModel. Гуглится в основном про QTableWidget.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.12.2018, 18:01
Ответы с готовыми решениями:

PyQt, редактируемый QTableView и автодобавление строк
Есть таблица, представляется классами myModel и myView. Не давно добавил возможность редактирования, с существующими значениями все хорошо,...

PYQT Вставить в ячейку QTableView произвольный виджет
Здравствуйте. Никак не могу понять, как вставить свой виджет отображения в ячейку QTableView. Есть назначение делегатов, но это...

Разница между PyQT 5 и PyQT 6
Добрый день, форумчане. Прошел тут курс всеми вами любимого автора, познакомился с GUI TKinter, и по вашим советам решил освоить PyQT. ...

60
 Аватар для Simply me
244 / 37 / 8
Регистрация: 05.05.2012
Сообщений: 521
03.01.2019, 07:40  [ТС]
Студворк — интернет-сервис помощи студентам
А посмотрите, пожалуйста, в чем ошибка при работе с делегатами. Хочу научиться. Делала по книжке. Вот класс делегата:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class MyDelegate(QtWidgets.QStyledItemDelegate):
    def createEditor(self, parent, options, index):
        # Компонент-редактор, используемый для правки значений количества позиций
        editor=QtWidgets.QSpinBox(parent)
        editor.setFrame(False)
        editor.setMinimum(1)
        editor.setMaximum(5)
        editor.setSingleStep(1)
        return editor
    def setEditorData(self, editor, index):
        # Заносим в компонент редактор значение количества
        value = int(index.model().data(index, QtCore.Qt.EditRole))
        editor.setValue(value)
    def updateEditorGeometry(self, editor, options, index):
        # Указываем размеры компонента-редактора
        editor.SetGeometry(options.rect)
    def setModelData(self, editor, model, index):
        # Заносим исправленное значение количества в модель
        value = str(editor.value())
        model.setData(index, value, QtCore.Qt.EditRole)
Вот так используется класс MyDelegate в функции __init__ класса MyWin
Python
1
2
3
4
5
6
7
8
9
class MyWin(QWidget):
    def __init__(self, data=None, parent=None):
        super().__init__()
        self.model = QStandardItemModel() # модель
        self.model.setHorizontalHeaderLabels(['Delegate', 'x', 'y(x)', 'sum(y)', 'Red-Green']) # заголовки модели
        self.table = QTableView() # таблица
        self.table.setModel(self.model) # передача модели в таблицу
        ..............................................................................
        self.table.setItemDelegateForColumn(0, MyDelegate())  # делегат в первом столбце таблицы
Вот главная функция:
Python
1
2
3
4
5
6
if __name__ == "__main__":
    app = QApplication([])
    myapp = MyWin(mass)
    myapp.setWindowTitle("Таблица и график")  # Заголовок окна
    myapp.show()
    app.exec_()
Когда запускаю и редактирую первый столбец таблицы, пишет: Прекращена работа Python.
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
03.01.2019, 15:31
https://github.com/baoboa/pyqt... elegate.py

Добавлено через 23 секунды
тут много примеров

Добавлено через 50 минут
Цитата Сообщение от Simply me Посмотреть сообщение
Когда запускаю и редактирую первый столбец таблицы, пишет: Прекращена работа Python.
в консоли смотрите ошибки. у вас синтаксис и импорты
0
 Аватар для Simply me
244 / 37 / 8
Регистрация: 05.05.2012
Сообщений: 521
05.01.2019, 20:18  [ТС]
Спасибо) но я всё-таки не совсем понимаю, в чем принципиальная разница между этим кодом, моим кодом и кодом из книжки. Хочу научиться, а не просто заменять свой неработающий код на чужой работающий.

Добавлено через 2 минуты
В консоли у меня в pycharm почему-то пишет только с каким кодом выполнилось. Если не ноль, то ошибка.
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
06.01.2019, 07:29
запускайте из терминала
Bash
1
python -v my_script
пайчарм не пользуюсь, для освоения вам вполне Geany хватит
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
07.01.2019, 08:38
КМК вы пытаетесь редактировать пустую модель, поэтому и вылетает
В PyQt5 ошибки Qt можно только в консоли увидеть. УМВР
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
#/usr/local/bin/python3
 
from PyQt5.QtWidgets import (QApplication, QWidget, QTableView, QPushButton,
QStyledItemDelegate,QDoubleSpinBox, QMenu)
from PyQt5.QtGui import QFont,QColor
from PyQt5.QtCore import (Qt, QAbstractTableModel, QModelIndex, QAbstractItemModel)
 
import numpy as np
 
class NpModel(QAbstractTableModel):
    def __init__(self, data = np.array([[]]), parent=None):
        super().__init__()
        self.npdata = data
        
    def rowCount(self,index=QModelIndex()):
        return len(self.npdata)
        
    def columnCount(self,index=QModelIndex()):
        return len(self.npdata[0])
    
    def data(self,index,role):
        if not index.isValid(): return None
        row = index.row()
        col = index.column()
        val = self.npdata[row,col]
        if role == Qt.DisplayRole or role == Qt.EditRole:
            return str(round(val,3))
        elif role == Qt.BackgroundRole:
            if col == 0: return QColor(0,0,0,8)
                        
    def flags(self,index):
        if not index.isValid(): return Qt.ItemIsEnabled
        if index.column() == 0:
            return Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable
        return Qt.ItemIsEnabled | Qt.ItemIsEditable
        
    def setData(self,index,value,role):
        if not index.isValid():
             return False
        if role == Qt.EditRole:
            try : f = float(value.replace(',','.'))
            except: return False
            self.npdata[index.row(),index.column()] = f
            self.dataChanged.emit(index,index)
            return True
        return False
 
    def headerData(self,section,orientation,role):
        if role != Qt.DisplayRole: return None
        if orientation == Qt.Horizontal:
            return 'Col:' + str(section + 1)
        else: return str(section + 1)
        
    def load(self,arr):
        self.beginResetModel()
        self.npdata = arr
        self.endResetModel()
        
class SpinDelegate(QStyledItemDelegate):
    def createEditor(self, parent, options, index):
        editor = QDoubleSpinBox(parent)
        editor.setFrame(False)
        editor.setRange(1,5)
        editor.setSingleStep(1)
        return editor
        
    def setEditorData(self, editor, index):
        value = index.model().data(index, Qt.EditRole)
        editor.setValue(float(value))
        
    def updateEditorGeometry(self, editor, options, index):
        editor.setGeometry(options.rect)
    
    def setModelData(self, editor, model, index):
        value = str(editor.value())
        model.setData(index, value, Qt.EditRole)
        
 
class NpView(QTableView):
    def __init__(self,parent=None):
        super().__init__()
        self.horizontalHeader().setSectionResizeMode(1)
        self.setSelectionMode(1)
        self.viewport().setAttribute(Qt.WA_StaticContents)
 
        
    def keyPressEvent(self,e):
        if e.key() == Qt.Key_Escape:
            self.clearSelection()
        
    def contextMenuEvent(self,e):
        pos = self.mapToGlobal(e.pos())
        mnu = QMenu()
        mnu.addAction('Cancel').setObjectName('cancel')
        mnu.addSeparator()
        mnu.addAction('Div').setObjectName('div')
        mnu.addSeparator()
        mnu.addAction('Mul').setObjectName('mul')
        ret  = mnu.exec_(pos)
        if ret:
            obj = ret.objectName()
            if obj == 'cancel':
                self.clearSelection()
                return
            rows = [i.row() for i in self.selectedIndexes()]
            if obj == 'div':
                for i in rows:
                    model.npdata[i,1:] /= model.npdata[i,0]
            elif obj == 'mul':
                for i in rows:
                    model.npdata[i,1:] *= model.npdata[i,0]
            self.model().layoutChanged.emit()
 
if __name__ == "__main__":
    app = QApplication([])
    l = np.arange(1,31,dtype=float).reshape(5,6)
    l[:,0] = 1
    model = NpModel(l)
    w = NpView()
    w.setItemDelegateForColumn(0,SpinDelegate())
    w.setModel(model)
    w.setFont(QFont('Times',16))
    w.resize(600,400)
    w.show()
    app.exec_()
Добавлено через 2 часа 25 минут
ДЛЯ ПРАКТИКИ- найдите ошибку
0
 Аватар для Simply me
244 / 37 / 8
Регистрация: 05.05.2012
Сообщений: 521
07.01.2019, 09:04  [ТС]
Цитата Сообщение от vic5710 Посмотреть сообщение
КМК вы пытаетесь редактировать пустую модель
Вроде не пустая модель. Таблица заполнена числами. И все столбцы, кроме того, которому присвоен делегат, нормально редактируются. а при редактировании первого столбца вылетает.

Запустила из терминала такой командой: python -v main. Вывел очень много текста. Первая часть вывода во вложении. Может, можно как-то запустить, чтобы только ошибки выводились?

Цитата Сообщение от vic5710 Посмотреть сообщение
ДЛЯ ПРАКТИКИ- найдите ошибку
Лучше Вы в моем коде
Миниатюры
Pyqt. Класс QTableView  
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
07.01.2019, 09:20
Цитата Сообщение от Simply me Посмотреть сообщение
чтобы только ошибки выводились?
Bash
1
python myscript
Добавлено через 56 секунд
Цитата Сообщение от Simply me Посмотреть сообщение
Лучше Вы в моем коде
я то найду, но сами писать так вы не научитесь
1
07.01.2019, 09:23  [ТС]

Не по теме:

Ну сложно начинать с разбора 100 строчек не своего кода)

0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
07.01.2019, 09:25
покажите весь код
0
 Аватар для Simply me
244 / 37 / 8
Регистрация: 05.05.2012
Сообщений: 521
07.01.2019, 09:36  [ТС]
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
import sys
# Импорт numpy
import numpy
# Импорт интерфейса
from test import *
 
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QTableView, QWidget, QGridLayout, QPushButton, QTreeView, QListView, QSpinBox
from PyQt5.QtGui import QStandardItemModel, QStandardItem
 
# Массив значений
mass = numpy.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], int)
 
 
# Класс делегата
class MyDelegate(QtWidgets.QStyledItemDelegate):
    def createEditor(self, parent, options, index):
        # Компонент-редактор, используемый для правки значений количества позиций
        editor=QtWidgets.QSpinBox(parent)
        editor.setFrame(False)
        editor.setMinimum(1)
        editor.setMaximum(5)
        editor.setSingleStep(1)
        return editor
    def setEditorData(self, editor, index):
        # Заносим в компонент редактор значение количества
        value = int(index.model().data(index, QtCore.Qt.EditRole))
        editor.setValue(value)
    def updateEditorGeometry(self, editor, options, index):
        # Указываем размеры компонента-редактора
        editor.SetGeometry(options.rect)
    def setModelData(self, editor, model, index):
        # Заносим исправленное значение количества в модель
        value = str(editor.value())
        model.setData(index, value, QtCore.Qt.EditRole)
 
 
class MyWin(QWidget):
    def __init__(self, data=None, parent=None):
        super().__init__()
        self.model = QStandardItemModel() # модель
        self.model.setHorizontalHeaderLabels(['Delegate', 'x', 'y(x)', 'sum(y)', 'Red-Green']) # заголовки модели
        self.table = QTableView() # таблица
        self.table.setModel(self.model) # передача модели в таблицу
        self.table.horizontalHeader().setSectionResizeMode(1) # размер таблицы по содержимому
        self.btnLoad = QPushButton("Load") # кнопка загрузки данных
        #self.btnCalc = QPushButton("Calc") # кнопка расчета
        #self.btnGet = QPushButton('Get') # кнопка расчета
        self.btnLoad.clicked.connect(self.load_data)
        #self.btnCalc.clicked.connect(self.calc)
        #self.btnGet.clicked.connect(self.get_data)
        grid = QGridLayout(self)
        grid.setContentsMargins(1, 1, 1, 1)
        grid.addWidget(self.table, 0, 0, 4, 4)
        grid.addWidget(self.btnLoad, 4, 0, 1, 1)
        #grid.addWidget(self.btnCalc, 4, 1, 1, 1)
        #grid.addWidget(self.btnGet, 4, 3, 1, 1)
        self.data = data
        self.table.setItemDelegateForColumn(0, MyDelegate())  # делегат в первом столбце таблицы
 
    def load_data(self):
        rows = len(self.data)
        cols = len(self.data[0])
        for row in range(rows):
            for col in range(cols):
                item = QStandardItem(str(self.data[row][col]))
                self.model.setItem(row, col, item)
 
if __name__ == "__main__":
    app = QApplication(sys.argv)
    myapp = MyWin(mass)
    myapp.setWindowTitle("Таблица и график")  # Заголовок окна
    myapp.show()
    app.exec_()
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
07.01.2019, 09:47
ну и где данные?
Миниатюры
Pyqt. Класс QTableView  
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
07.01.2019, 09:50
Bash
1
2
3
4
  File "t.py", line 31, in updateEditorGeometry
    editor.SetGeometry(options.rect)
AttributeError: 'QSpinBox' object has no attribute 'SetGeometry'
Abort trap: 6
0
 Аватар для Simply me
244 / 37 / 8
Регистрация: 05.05.2012
Сообщений: 521
07.01.2019, 10:00  [ТС]
Данные будут, если на кнопку load нажать. Вообще они в переменной mass. Они передаются в экземпляр класса MyWin. Как я понимаю.
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
07.01.2019, 10:02
я вам уже ошибку показал
1
 Аватар для Simply me
244 / 37 / 8
Регистрация: 05.05.2012
Сообщений: 521
07.01.2019, 10:33  [ТС]
Спасибо, действительно у класса QSpinBox нет свойства setGeometry. Хотя во всех просмотренных мной примерах создания делегата используется это свойство этого класса. Наверное, с версией связано. Подумаю, как по-другому задать размер делегата.
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
07.01.2019, 10:55
Цитата Сообщение от Simply me Посмотреть сообщение
Спасибо, действительно у класса QSpinBox нет свойства setGeometry. Хотя во всех просмотренных мной примерах создания делегата используется это свойство этого класса. Наверное, с версией связано. Подумаю, как по-другому задать размер делегата.
вы серьезно?
https://github.com/baoboa/pyqt... elegate.py
0
 Аватар для Simply me
244 / 37 / 8
Регистрация: 05.05.2012
Сообщений: 521
08.01.2019, 07:43  [ТС]
Серьезно. В коде по ссылке тоже используется свойство setGeometry класса QSpinBox
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,763
08.01.2019, 08:02
а не проще писать без ошибок?
Цитата Сообщение от vic5710 Посмотреть сообщение
editor.SetGeometry(options.rect)
Цитата Сообщение от vic5710 Посмотреть сообщение
editor.setGeometry(options.rect)
1
 Аватар для Simply me
244 / 37 / 8
Регистрация: 05.05.2012
Сообщений: 521
08.01.2019, 08:05  [ТС]
Спасибо! Не заметила)))
0
 Аватар для Simply me
244 / 37 / 8
Регистрация: 05.05.2012
Сообщений: 521
12.01.2019, 09:15  [ТС]
vic5710, а можно поспрашивать по коду из сообщения 19?

1. Метод headerData класса NpModel, по-моему, нигде не вызывается. Но заголовки подписываются. Почему так?
2. Зачем beginResetModel, endResetModel, layoutChanged.emit? emit - это вроде имитация события.
3. Где запрещается редактирование ячеек пользователем?

В моем коде пользователь может редактировать ячейки. Но введенные значения не попадают в модель. Функция calc считает по изначально загруженным значениям. А если расскомментировать эту строчку, то программа вылетает:
Python
1
self.model.itemChanged.connect(self.calc)
Вот функция calc
Python
1
2
3
4
5
6
7
8
9
10
def calc(self):
        # пересчет значений 3 столбца из значений 2 столбца
        # в 4 столбце накопленные значения из 3 столбца
        for i in range(len(self.data)):
            self.data[i][2] = 100 * self.data[i][1]
            self.load_data()
            self.data[0][3] = self.data[0][2]
            for i in range(1, len(self.data)):
                self.data[i][3] = self.data[i - 1][3] + self.data[i][2]
            self.load_data()
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
12.01.2019, 09:15
Помогаю со студенческими работами здесь

Из QT в PyQt
Здравствуйте, подскажите правильно ли у меня получился перевод из QT в PyQt? Интересует именно выполнение класса QCoreApplication и...

PyQt, Qt и ScrollArea
Доброй ночи. В этот раз кода не будет, так как клин. Из русскоязычных мануалов по PyQt только Прохоренок, которого все хаят (а...

PyQt + PyCharm
Как подключить PyQT5 к pycharm 4.5.3 ? python 3.4

PyQt и Spyder 3
Доброго времени суток! Возyикает проблема после установки PyQt - перестает запускаться Spyder 3, никаких ошибок, ничего. Запускаешь IDE,...

Paint pyqt
Добрый вечер, помогите разобраться с кодом я в Python (pyqt, Desinger) новичок. Можете обяснить по подробнее с "Class Canvas"...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
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
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru