Как построить динамическую таблицу QTableWidget используя алгоритм Хаффмана
Как при открытии текстового файла, в котором есть неопределённое количество символов, построить таблицу (QTableWidget) вероятностей для этих символов по алгоритму Хаффмана.
test.py:
from PySide2.QtCore import (QCoreApplication, QMetaObject, QObject, QPoint,
QRect, QSize, QUrl, Qt)
from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont,
QFontDatabase, QIcon, QLinearGradient, QPalette, QPainter, QPixmap,
QRadialGradient)
from PySide2.QtWidgets import *
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.verticalLayout = QVBoxLayout(self.centralwidget)
self.verticalLayout.setSpacing(0)
self.verticalLayout.setObjectName(u"verticalLayout")
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.frame = QFrame(self.centralwidget)
self.frame.setObjectName(u"frame")
self.frame.setMinimumSize(QSize(0, 0))
self.frame.setMaximumSize(QSize(16777215, 30))
self.frame.setFrameShape(QFrame.NoFrame)
self.frame.setFrameShadow(QFrame.Raised)
self.horizontalLayout = QHBoxLayout(self.frame)
self.horizontalLayout.setSpacing(0)
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.pushButton = QPushButton(self.frame)
self.pushButton.setObjectName(u"pushButton")
self.horizontalLayout.addWidget(self.pushButton, 0, Qt.AlignLeft)
self.verticalLayout.addWidget(self.frame)
self.frame_2 = QFrame(self.centralwidget)
self.frame_2.setObjectName(u"frame_2")
self.frame_2.setFrameShape(QFrame.NoFrame)
self.frame_2.setFrameShadow(QFrame.Raised)
self.verticalLayout_2 = QVBoxLayout(self.frame_2)
self.verticalLayout_2.setSpacing(0)
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
self.tableWidget = QTableWidget(self.frame_2)
self.tableWidget.setObjectName(u"tableWidget")
self.verticalLayout_2.addWidget(self.tableWidget)
self.verticalLayout.addWidget(self.frame_2)
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QStatusBar(MainWindow)
self.statusbar.setObjectName(u"statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
# setupUi
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
self.pushButton.setText(QCoreApplication.translate("MainWindow", u"\u041e\u0442\u043a\u0440\u044b\u0442\u044c", None))`
main.py:
import sys
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import (QCoreApplication, QPropertyAnimation, QDate, QDateTime, QMetaObject, QObject, QPoint, QRect, QSize, QTime, QUrl, Qt, QEvent)
from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont, QFontDatabase, QIcon, QKeySequence, QLinearGradient, QPalette, QPainter, QPixmap, QRadialGradient)
from PySide2.QtWidgets import *
from test import Ui_MainWindow# импорт нашего сгенерированного файла
class mywindow(QMainWindow):
def __init__(self):
super(mywindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.pushButton.clicked.connect(self.open)
self.show()
def open(self):
res = QFileDialog.getOpenFileName(self , 'Открыть файл')
if __name__ == "__main__":
app = QApplication(sys.argv)
window = mywindow()
sys.exit(app.exec_())
Пример таблицы:
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Я не знаком с алгоритмом Хаффмана и вы не предоставили алгоритм Хаффмана.
Я взял предложенный Google "Жадный алгоритм код Хаффмана..."
и построил для вас таблицу в QTableWidget.
Текстовый файл huffman.txt прилагается.
Поменяйте импорты для PySide2 и попробуйте.
main.py
import sys
'''
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import (QCoreApplication, QPropertyAnimation, QDate, QDateTime, QMetaObject, QObject, QPoint, QRect, QSize, QTime, QUrl, Qt, QEvent)
from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont, QFontDatabase, QIcon, QKeySequence, QLinearGradient, QPalette, QPainter, QPixmap, QRadialGradient)
from PySide2.QtWidgets import *
'''
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *
#from test import Ui_MainWindow # импорт нашего сгенерированного файла
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.verticalLayout = QVBoxLayout(self.centralwidget)
self.verticalLayout.setSpacing(0)
self.verticalLayout.setObjectName(u"verticalLayout")
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.frame = QFrame(self.centralwidget)
self.frame.setObjectName(u"frame")
self.frame.setMinimumSize(QSize(0, 0))
self.frame.setMaximumSize(QSize(16777215, 30))
self.frame.setFrameShape(QFrame.NoFrame)
self.frame.setFrameShadow(QFrame.Raised)
self.horizontalLayout = QHBoxLayout(self.frame)
self.horizontalLayout.setSpacing(0)
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.pushButton = QPushButton(self.frame)
self.pushButton.setObjectName(u"pushButton")
self.horizontalLayout.addWidget(self.pushButton, 0, Qt.AlignLeft)
self.verticalLayout.addWidget(self.frame)
self.frame_2 = QFrame(self.centralwidget)
self.frame_2.setObjectName(u"frame_2")
self.frame_2.setFrameShape(QFrame.NoFrame)
self.frame_2.setFrameShadow(QFrame.Raised)
self.verticalLayout_2 = QVBoxLayout(self.frame_2)
self.verticalLayout_2.setSpacing(0)
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
self.tableWidget = QTableWidget(self.frame_2)
self.tableWidget.setObjectName(u"tableWidget")
self.verticalLayout_2.addWidget(self.tableWidget)
self.verticalLayout.addWidget(self.frame_2)
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QStatusBar(MainWindow)
self.statusbar.setObjectName(u"statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", "MainWindow"))
self.pushButton.setText(QCoreApplication.translate("MainWindow", "Открыть"))
# Создать класс узла
class Node(object):
def __init__(self, name=None, value=None):
self.name = name
self.value = value
self.lchild = None
self.rchild = None
# Создать дерево Хаффмана
class HuffmanTree(object):
# По идее дерева Хаффмана:
# на основе узла построить дерево Хаффмана в обратном порядке
def __init__(self, char_Weights):
self.char_Weights = char_Weights
self.Leaf = [Node(k,v) for k, v in char_Weights.items()]
while len(self.Leaf) != 1:
self.Leaf.sort(key=lambda node:node.value, reverse=True)
n = Node(value=(self.Leaf[-1].value + self.Leaf[-2].value))
n.lchild = self.Leaf.pop(-1)
n.rchild = self.Leaf.pop(-1)
self.Leaf.append(n)
self.root = self.Leaf[0]
self.Buffer = list(range(10))
# Создавать коды с рекурсивным мышлением
def Hu_generate(self, tree, length):
node = tree
if (not node):
return
elif node.name:
buffer = []
#print(f'{node.name} Кодировка Хаффмана: ', end='')
for i in range(length):
#print(self.Buffer[i], end='')
buffer.append(self.Buffer[i])
self.char_Weights[node.name] = [
str(self.char_Weights[node.name]),
''.join(map(str, buffer))
]
#print('')
return
self.Buffer[length] = 0
self.Hu_generate(node.lchild, length + 1)
self.Buffer[length] = 1
self.Hu_generate(node.rchild, length + 1)
#Output кодировка Хаффмана
def get_code(self):
self.Hu_generate(self.root, 0)
class MyWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.setupUi(self)
self.pushButton.clicked.connect(self.open_file)
def open_file(self):
path_file, _ = QFileDialog.getOpenFileName(
self,
'Открыть файл',
'.',
'Text Files(*.txt)' # huffman.txt
)
if not path_file:
return
self.result = self.findTheCharFrequency(path_file)
tree = HuffmanTree(self.result)
tree.get_code()
self.tableWidget.clear()
self.tableWidget.setRowCount(0)
self.tableWidget.setColumnCount(3)
self.tableWidget.setHorizontalHeaderLabels(
['Символ', 'Вероятностей каждого символа', 'Кодировка Хаффмана'])
self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
self.tableWidget.verticalHeader().hide()
list_keys = list(tree.char_Weights.keys())
list_keys.sort()
for i in list_keys:
v, k = tree.char_Weights[i]
rowPosition = self.tableWidget.rowCount()
self.tableWidget.insertRow(rowPosition)
self.tableWidget.setItem(rowPosition, 0, QtWidgets.QTableWidgetItem(i))
self.tableWidget.setItem(rowPosition, 1, QtWidgets.QTableWidgetItem(v))
self.tableWidget.setItem(rowPosition, 2, QtWidgets.QTableWidgetItem(k))
# Подготовить таблицу вероятностей каждого символа
def findTheCharFrequency(self, text):
# частота каждого символа дается в виде словаря
result = dict()
with open(text, 'r', encoding='utf-8') as f:
for line in f.readlines():
line = line.lower()
for i in line:
if i.isalpha(): # Определить, является ли символ буквой
if i in result:
result[i] += 1
else:
result.update({i:1})
return result
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
huffman.txt
ХаффманаКак построить динамическую таблицу в QTableWidget используя алгоритм Хаффмана
Хаффмана Как при открытии текстового файла, в котором есть неопределённое количество символов.
Хаффмана построить таблицу вероятностей для этих символов по алгоритму Хаффмана.

