LINUX.ORG.RU

Медленная прорисовка таблицы

 ,


0

1

Привет всем!

Мне надо создать таблицу на 124 строки и 5 столбцов, при этом текст в любой из ячеек таблицы может иметь разный цвет, гарнитуру и кегель. Поскольку одна и та же ячейка в QTableWidget не может иметь несколько шрифтов одновременно (если верить форумам), то для каждой ячейки приходится предварительно создавать QLabel. И все бы ничего, на моем хиленьком нетбуке прорисовка таблицы (с созданием QLabel, без доп. шрифтов) занимает 1 с, однако, когда я пытаюсь раскрасить таблицу (см. «<span style=' в коде), на прорисовку уходит 3,6-4 с. Как-то многовато. Нельзя ли как-нибудь оптимизировать?

ЛОР не дает вставить весь код, см. его полностью здесь. Вот основная часть кода (без данных для вставки):

#!/usr/bin/python3
from PyQt5.QtGui import * 
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
from time import time

col_limit=5
width = 1024
height = 768

db_elem = {} # skipped

# Show a table with article entries
def show_article(cells):
	start=time()
	app = QApplication(sys.argv)
	table = QTableWidget()
	table.resize(width,height)
	assert len(cells) > 0
	assert col_limit >= 2
	table.setRowCount(len(cells))
	table.setColumnCount(col_limit)
	# Insert data into the table
	for i in range(len(cells)):
		for j in range(col_limit):
			label=QLabel()
			#label.setText(cells[i][j]['dic'] + cells[i][j]['term'] + cells[i][j]['comment'])
			label.setText("<span style='font-size:12pt;color:navy;'>%s</span><span style='font-size:12pt;'>%s</span><span style='font-size:10pt;color:gray;'>%s</span>" % (cells[i][j]['dic'],cells[i][j]['term'],cells[i][j]['comment']))
			label.setWordWrap(True)
			label.setAlignment(Qt.AlignLeft|Qt.AlignTop)
			table.setCellWidget(i,j,label)
	# We assume that the first column contains dictionary titles and must be narrower than other columns
	first_col=int((width/col_limit)*0.7)
	standard_col=(width-first_col)/(col_limit-1)
	table.setColumnWidth(0,first_col)
	i=1
	while i < len(cells):
		table.setColumnWidth(i,standard_col)
		i+=1
	# Set a text resize mode
	# If you are using Qt 5, QHeaderView::setResizeMode() is no longer available. Instead, you can use QHeaderView::setSectionResizeMode(). Just call it for every column.
	for i in range(len(cells)):
		table.verticalHeader().setSectionResizeMode(i,QHeaderView.ResizeToContents)
	end=time()
	print('Table has been drawn in %s sec.' % str(end-start))
	table.show()
	app.exec_()

show_article(cells)
Deleted

Попробуй QTableView с соответствующей моделью. Сначала создаешь модель, заполняешь её данными и скармливаешь QTableView. QTableWidget для совсем простеньких таблиц.

hippi90 ★★★★★
()

Ну да, setCellWidget в QTableWidget тот ещё тормоз. Он каждый раз перерисовывает всю таблицу при вставке нового виджета.

anonymous
()
5 декабря 2015 г.
Ответ на: комментарий от hippi90

На основе примеров из Интернета написал вот такой код.

#!/usr/bin/python3

from PyQt5.QtCore import *
from PyQt5.QtGui import * 
from PyQt5.QtWidgets import *
from time import time
import sys

my_array = [['Общая лексика','класс (the top of the class - первый ученик (в классе))','разряд','группа','категория (class of problems - круг вопросов)'],
            ['','вид','род','сорт','качество'],
            ['','отличие','курс (to take classes (in) - проходить курс обучения (где-либо))','группа','отряд'],
            ['Генетика','класс (Набор характеристик, задающих общие свойства окон, принадлежащих данному классу)','','','']]

class MyWindow(QWidget):
	def __init__(self, *args):
		QWidget.__init__(self, *args)

		tablemodel = MyTableModel(my_array, self)
		tableview = QTableView()
		tableview.setModel(tablemodel)
		
		tableview.verticalHeader().setVisible(False)
		tableview.horizontalHeader().setVisible(False)
		
		#tableview.setRowCount(4) - not supported
		#tableview.setColumnCount(5) - not supported
		
		tableview.setSpan(3,1,1,4)

		tableview.verticalHeader().setSectionResizeMode(0,QHeaderView.ResizeToContents)
		tableview.verticalHeader().setSectionResizeMode(1,QHeaderView.ResizeToContents)
		tableview.verticalHeader().setSectionResizeMode(2,QHeaderView.ResizeToContents)
		tableview.verticalHeader().setSectionResizeMode(3,QHeaderView.ResizeToContents)
		
		tableview.setShowGrid(False)
		
		label = QLabel()
		label.setText("<span style='font-size:12pt;color:navy;'>'Общая лексика'</span>")
		label.setWordWrap(True)
		#label.setFont(cell_font)
		label.setAlignment(Qt.AlignLeft|Qt.AlignTop)
		my_array[0] = label
		
		layout = QVBoxLayout(self)
		layout.addWidget(tableview)
		self.setLayout(layout)

class MyTableModel(QAbstractTableModel):
	def __init__(self, datain, parent=None, *args):
		QAbstractTableModel.__init__(self, parent, *args)
		self.arraydata = datain

	def rowCount(self, parent):
		#return len(self.arraydata)
		return 4

	def columnCount(self, parent):
		#return len(self.arraydata[0])
		return 5

	def data(self, index, role):
		if not index.isValid():
			return QVariant()
		elif role != Qt.DisplayRole:
			return QVariant()
		try:
			return QVariant(self.arraydata[index.row()][index.column()])
		except:
			return QVariant()

if __name__ == '__main__':
	start_time = time()
	app = QApplication(sys.argv)
	w = MyWindow()
	w.show()
	w.setWindowTitle('<Article Title>')
	w.resize(1024,768)
	end_time = time()
	print('Завершено за %s с.' % (str(end_time - start_time)))
	sys.exit(app.exec_())
Руководства и форумы по QT5 я подчитал, но, в целом, еще полный нуб. По моделям плохо понимаю, мозги пухнут. Подскажите, пожалуйста:

1) Как использовать QLabel в QTableView? Почему не вставляется QLabel в коде выше?

2) Почему после объединения ячеек по вертикали остается много пустого места (см. скрин)?

3) Можно ли в QTableView наследовать методы из QTableWidget?

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

Хм, для label оказалось достаточно сделать

label = QLabel(tableview)
label.show()
А как насчет остального?

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.