这学期的信息论与编码的课设需要用编程语言实现霍夫曼、费诺以及香农编码,要具备在windows下的可视化操作界面,因此就选用PyQt作为开发工具,本篇博客记录一下PyQt的基础以及课设的实例

参考:

《PyQt5从入门到实践》

PyQt5官方帮助文档

QApplication

[PyQt5]点击主窗口弹出另一个窗口

【PyQt】点击一个窗口的按钮来打开另一个窗口

Python 算法(2) 哈夫曼编码 Huffman Encoding

Python实现香农编码和费诺编码

[python]Huffman Encoding哈夫曼编码

PyQt基础

PyQt就是Qt的python接口,目前主要有3个版本:PyQt3、PyQt4以及PyQt5,其中PyQt5不向下兼容PyQt4,且官方默认只提供对python3.x的支持

PyQt5的主要的类如下:



PyQt5的主要模块如下:

开发环境搭建

开发的工具如下:

  • Python
  • Pycharm
  • Packet
    • pyqt5
    • pyqt5-tools
    • pyqt5designer

这里就记录一下如何在Pycharm中配置PyQt5,首先要安装需要的工具包:

接着要配置一些工具(PyQt5创建GUI图形用户界面程序时,会生成扩展名为.ui的文件,因此需要工具将其转换为.py文件;同时还需要PyQt5的设计器):

  • 添加安装pyqt5designer模块时自动安装的designer.exe,在Working directory中输入$ProjectFileDir$,表示项目文件目录

  • 添加将.ui文件转换为.py文件的转换工具,选择虚拟环境目录下的python.exe(Scripts文件夹中),然后在Arguments输入将.ui文件转换为.py文件的命令,在Working directory中输入$FileDir$,表示.ui文件所在的路径

完成配置后,在Tools->External Tools中可以看到这两个工具:

Qt Designer

Qt Designer是一个可视化GUI设计工具,可以在Tools中直接打开,直接显示新建窗体窗口,列举了Qt支持的几种窗口类型:

  • Dialog with Buttons Bottom:按钮在底部的对话框窗口
  • Dialog with Buttons Right:按钮在右上角的对话框窗口
  • Dialog without Buttons:没有按钮的对话框窗口
  • Main Window:一个带菜单、停靠窗口和状态栏的主窗口
  • Widget:通用窗口

选择后就可以开始设计,Qt Designer的几个主要组成部分如下:

  • 菜单栏
  • 工具栏
  • 工具箱
  • 窗口设计区域
  • 对象查看器
  • 属性编辑器
  • 信号/槽、动作、资源编辑器

同时可以在Widget Box工具箱中选用相应的控件即可开始设计自己的GUI

  • 如果设计完成,可以在窗体->预览于选择预览方式,观察实际运行的效果
  • 可以在窗体->View Python Code中查看对应的Python代码;也可以直接在pycharm中选择保存好的.ui文件,选择Tools->External Tool->PyUIC即可

生成了代码后还需要设置程序入口并显示,代码如下:

import sys
import coding # coding就是通过.ui文件生成的.py文件,.ui文件的名字是什么就import什么
from PyQt5 import QtCore, QtGui, QtWidgets if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = coding.Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())

关于这个程序的理解:

  • sys模块提供访问由解释器使用或维护的变量的接口,并提供了一些函数和解释器进行交互,操控python运行时的环境

    • sys.argv:
    • sys.exit:
  • QtWidgets模块包含了构建界面的一系列UI元素组件
    • QApplication:对于任一使用Qt的GUI应用,只能有一个QApplication对象
    • QMainWindow:QMainWindow是Qt的顶层窗口,使用它代表创建窗体对象
  • Ui_MainWindow就是.ui文件转换为.py文件生成的类,setupUi就是对对象进行初始化设置
  • MainWindow.show()用于显示窗体

PyQt5窗口设计基础

PyQt5的窗口就是向用户展示信息的可视化界面,是GUI程序的基本单元

PyQt5窗口创建完成后,可以通过属性对窗口进行设置,这些属性可以在属性编辑器中进行设置,也可以直接通过代码来实现,其常用的属性如下:

  • 窗口的对象名称,相当于窗口的标识,是唯一的,在编写代码时,对窗口的任何设置和使用都是通过该名称进行操作的,默认名称是MainWindow,可通过objectName来进行修改



    如果需要使用python代码进行设置的话,需要使用一个函数:MainWindow.setObjectName("MainWindow")
  • 窗口的标题栏名称通过windowTitle设置,也可以直接用python中的函数:MainWindow.setWindowTitle("标题栏")
  • 窗口的大小通过geometry属性设置,也可以直接用python中的函数:MainWindow.resize(252,100)
  • 窗口的样式可以使用setWindowFlags()函数设置:setWindowFlags(Qt.WindowFlags),其中Qt.WindowFlags参数表示要设置的窗口样式
    • 对窗口样式的设置要在初始化窗体后才会起作用,即要在setupUi()函数后执行

信号与槽

信号(signal)与槽(slot)是Qt的核心机制,也是进行PyQt5编程时对象之间通信的基础,在PyQt5中,每一个QObject对象(包括各种窗口和控件)都支持信号与槽机制,通过信号与槽的关联就可以实现对象之间的通信,当信号发射时,连接的槽函数(方法)将会自动执行,在PyQt5中,信号与槽是通过对象的signal.connect()方法进行连接

PyQt5的窗口控件中有很多内置的信号与槽,PyQt5中使用信号与槽的主要特点如下:

  • 一个信号可以连接多个槽
  • 一个槽可以监听多个信号
  • 信号与信号之间可以互连
  • 信号与槽的连接可以跨线程
  • 信号与槽的连接方式可以是同步,也可以是异步
  • 信号的参数可以是任何的python类型

接下来用一个简例通过信号与槽实现一个单击按钮关闭主窗口的效果:

  • 首先添加一个PushButton,并设置按钮的text属性为"关闭"

  • 在菜单栏中选择"编辑信号/槽",然后选中关闭按钮,按住鼠标左键拖动至窗口的空白区域

  • 松开鼠标后,会自动弹出配置连接,选中"显示从QWidget继承的信号和槽"复选框,然后在上方的信号与槽列表分别选中"clicked()"和"close()",完成信号与槽的关联

  • 使用PyUIC工具将.ui文件转换为.py文件,然后编写python显示窗口并测试

PyQt5的常用控件

控件是用户可以用来输入或操作数据的对象,在PyQt5中控件的基类是QFrame类,而QFrame类继承自QWidget类,QWidget类是所有用户界面对象的基类

Qt Designer中默认对控件进行了分组:

















文本类控件

文本类控件主要用来显示或者编辑文本信息

Label:标签控件

主要用于显示用户不能编辑的文本,标识窗体上的对象,对应PyQt5中的QLabel类(QLabel类属于QtWidgets),Label控件本质上是QLabel类的一个对象

  • 设置标签文本:在Qt Designer中的属性编辑器中设置text属性/用QLabel类的setText()方法
  • 设置标签文本的对齐方式:在Qt Designer中的属性编辑器中设置alignment属性中的Horizontal和Vertical/用QLabel类的setAlignment()方法
    • Horizontal用于设置标签文本的水平对齐方式

      • AlignLeft:左对齐
      • AlignHCenter:水平居中对齐
      • AlignRight:右对齐
    • Vertical用于设置标签文本的垂直对齐方式
      • AlignTop:顶部对齐
      • AlignVCenter:垂直居中对齐
      • AlignBottom:底部对齐
  • 设置文本换行显示:在标签宽度不足的情况下,系统会默认只显示部分文字,可以设置标签中的文本换行显示,在Qt Designer中的属性编辑器中将wordWrap属性后面的复选框选中/用QLabel类的setWordWrap方法
  • 获取标签文本:用QLabel类的text()方法

LineEdit:单行文本框

LineEdit是单行文本框,该控件只能输入单行字符串,对应PyQt5中的QLineEdit类,该类的常用方法如下:

  • setText():设置文本框内容
  • text():获取文本框内容
  • setPlaceholderText():设置文本框浮现文字
  • setMaxLength():设置允许文本框内输入字符的最大长度
  • setAlignment():设置文本对齐方式
  • setReadOnly():设置文本框只读
  • setEchoMode():设置文本框显示字符的模式
    • QLineEdit.Normal:正常显示输入的字符,默认设置
    • QLineEdit.NoEcho:不显示任何输入的字符,适用于即使符合密码长度也需要保密的密码
    • QLineEdit.Password:显示与平台相关的密码掩码字符,而不是实际输入的字符
  • setValidator():设置文本框验证器
    • QIntValidator:限制输入整数
    • QDoubleValidator:限制输入小数
    • QRegExpValidator:检查输入是否符合设置的正则表达式
  • clear():清除文本框内容

QLineEdit类的常用信号:

  • textChanged:当更改文本框中的内容时发射该信号
  • editingFinished:当文本框中的内容编辑结束后发射该信号,以按下enter键为编辑结束标志

TextEdit:多行文本框

TextEdit是多行文本框控件,主要用来显示多行的文本内容,当文本内容超出控件的显示范围时,该控件将显示垂直滚动条,该类的常用方法如下:

  • setPlainText():设置文本内容
  • toPlainText():获取文本内容
  • setTextColor():设置文本颜色
  • setWordWrapMode():设置自动换行
  • clear():清除所有内容

按钮类控件

按钮类控件主要用来执行一些命令操作

PushButton:按钮

PushButton允许用户通过单击来执行操作,既可以显示文本,也可以显示图像,当该控件被单击时,它看起来的状态像是被按下,然后被释放,对应PyQt5中的QPushButton类,该类的常用方法如下:

  • setText():设置按钮显示的文本
  • text():获取按钮显示的文本
  • setIcon():设置按钮上的图标,可以将参数设置为QtGui.QIcon('图标路径')
  • setIconSize():设置按钮图标的大小,参数可以设置为Qtcore.Qsize(int width, int height)
  • setEnabled():设置按钮是否可用,参数设置为False时,按钮为不可用状态
  • setShortcut():设置按钮的快捷键,参数可设置为键盘中的按键或组合键

PushButton按钮中最常用的信号是clicked,当按钮被单击时,会发射该信号执行相应的操作

实例:信息论与编码课程设计

课程设计要求

利用编程语言实现霍夫曼、费诺、香农编码

  • 编码要求

    • 霍夫曼编码:实现任意Q符号的N重序列信源的最优R进制编码(8≤Q≤15;2≤R≤5;1≤N≤3)
    • 费诺、香农编码:实现任意Q符号的二进制编码(Q≥10)
  • 编程要求
    • 编写的程序应具备在windows下的可视化操作界面,不同的编码类型用不同的菜单加以分割
    • 对于霍夫曼编码应该具备Q、N、R的能力,而费诺、香农编码能输入Q
    • 不同编码类型应当展现编码的结果,平均码长、信息熵等性能指标

设计流程

首先要在Qt designer中创建几个窗口,然后要将各个按键对应显示窗口的函数,然后根据几个编码过程编写代码然后在相应的控件上显示即可,这里给出三个编码的核心代码:

霍夫曼编码:

    def Hoffman_Coding(self):
Q,N,R,sp = self.Read_Input()
if Q == 0 and N == 0 and R == 0 and sp == 0:
self.ui_error.show()
return 0
all_sym = self.Get_All_Symbol(Q,N,R,sp) # all nodes
if R == 2:
hoffman_tree = self.Hoffman_Tree_Generate_2(Q,N,sp,all_sym)
hoffman_code = self.Coding_2(all_sym,hoffman_tree)
outcome = ''
for i in range(len(all_sym)):
outcome = outcome + str(round(all_sym[i].P,6)) + ' ' + hoffman_code[i] + ' ' +'\n'
# print(outcome)
self.textEdit_2.setPlainText(outcome)
self.Calculate_Performance_Index(N,R,sp,all_sym,hoffman_code)
elif R == 3:
hoffman_tree = self.Hoffman_Tree_Generate_3(Q,N,sp,all_sym)
hoffman_code = self.Coding_3(all_sym, hoffman_tree)
outcome = ''
for i in range(len(all_sym)):
outcome = outcome + str(round(all_sym[i].P, 6)) + ' ' + hoffman_code[i] + ' ' + '\n'
self.textEdit_2.setPlainText(outcome)
self.Calculate_Performance_Index(N, R, sp, all_sym, hoffman_code)
elif R == 4:
hoffman_tree = self.Hoffman_Tree_Generate_4(Q,N,sp,all_sym)
hoffman_code = self.Coding_4(all_sym, hoffman_tree)
outcome = ''
for i in range(len(all_sym)):
outcome = outcome + str(round(all_sym[i].P, 6)) + ' ' + hoffman_code[i] + ' ' + '\n'
self.textEdit_2.setPlainText(outcome)
self.Calculate_Performance_Index(N, R, sp, all_sym, hoffman_code)
elif R == 5:
hoffman_tree = self.Hoffman_Tree_Generate_5(Q,N,sp,all_sym)
hoffman_code = self.Coding_5(all_sym, hoffman_tree)
outcome = ''
for i in range(len(all_sym)):
outcome = outcome + str(round(all_sym[i].P, 6)) + ' ' + hoffman_code[i] + ' ' + '\n'
self.textEdit_2.setPlainText(outcome)
self.Calculate_Performance_Index(N, R, sp, all_sym, hoffman_code) def Hoffman_Tree_Generate_2(self,Q,N,sp,all_sym):
queue = all_sym[:]
while len(queue) > 1:
queue.sort(key=lambda item:item.P)
node_child1 = queue.pop(0)
node_child2 = queue.pop(0)
node_father = Node_2(node_child1.P + node_child2.P)
node_father.child1 = node_child1
node_father.child2 = node_child2
node_child1.father = node_father
node_child2.father = node_father
queue.append(node_father)
queue[0].father = None
return queue[0] def Hoffman_Tree_Generate_3(self,Q,N,sp,all_sym):
queue = all_sym[:]
while len(queue) > 1:
queue.sort(key=lambda item:item.P)
node_child1 = queue.pop(0)
node_child2 = queue.pop(0)
node_child3 = queue.pop(0)
node_father = Node_3(node_child1.P + node_child2.P + node_child3.P)
node_father.child1 = node_child1
node_father.child2 = node_child2
node_father.child3 = node_child3
node_child1.father = node_father
node_child2.father = node_father
node_child3.father = node_father
queue.append(node_father)
queue[0].father = None
return queue[0] def Hoffman_Tree_Generate_4(self,Q,N,sp,all_sym):
queue = all_sym[:]
while len(queue) > 1:
queue.sort(key=lambda item:item.P)
node_child1 = queue.pop(0)
node_child2 = queue.pop(0)
node_child3 = queue.pop(0)
node_child4 = queue.pop(0)
node_father = Node_4(node_child1.P + node_child2.P + node_child3.P + node_child4.P)
node_father.child1 = node_child1
node_father.child2 = node_child2
node_father.child3 = node_child3
node_father.child4 = node_child4
node_child1.father = node_father
node_child2.father = node_father
node_child3.father = node_father
node_child4.father = node_father
queue.append(node_father)
queue[0].father = None
return queue[0] def Hoffman_Tree_Generate_5(self,Q,N,sp,all_sym):
queue = all_sym[:]
while len(queue) > 1:
queue.sort(key=lambda item:item.P)
node_child1 = queue.pop(0)
node_child2 = queue.pop(0)
node_child3 = queue.pop(0)
node_child4 = queue.pop(0)
node_child5 = queue.pop(0)
node_father = Node_5(node_child1.P + node_child2.P + node_child3.P + node_child4.P + node_child5.P)
node_father.child1 = node_child1
node_father.child2 = node_child2
node_father.child3 = node_child3
node_father.child4 = node_child4
node_father.child5 = node_child5
node_child1.father = node_father
node_child2.father = node_father
node_child3.father = node_father
node_child4.father = node_father
node_child5.father = node_father
queue.append(node_father)
queue[0].father = None
return queue[0] def Coding_2(self,all_sym,root):
codes = ['']*len(all_sym)
for i in range(len(all_sym)):
node_tem = all_sym[i]
while node_tem != root:
if node_tem.check_num_of_child() == 1:
codes[i] = '0' + codes[i]
else:
codes[i] = '1' + codes[i]
node_tem = node_tem.father
print(codes)
return codes def Coding_3(self, all_sym, root):
codes = ['']*len(all_sym)
for i in range(len(all_sym)):
node_tem = all_sym[i]
while node_tem != root:
if node_tem.check_num_of_child() == 1:
codes[i] = '0' + codes[i]
elif node_tem.check_num_of_child() == 2:
codes[i] = '1' + codes[i]
else:
codes[i] = '2' + codes[i]
node_tem = node_tem.father
print(codes)
return codes def Coding_4(self, all_sym, root):
codes = ['']*len(all_sym)
for i in range(len(all_sym)):
node_tem = all_sym[i]
while node_tem != root:
if node_tem.check_num_of_child() == 1:
codes[i] = '0' + codes[i]
elif node_tem.check_num_of_child() == 2:
codes[i] = '1' + codes[i]
elif node_tem.check_num_of_child() == 3:
codes[i] = '2' + codes[i]
else:
codes[i] = '3' + codes[i]
node_tem = node_tem.father
print(codes)
return codes def Coding_5(self, all_sym, root):
codes = ['']*len(all_sym)
for i in range(len(all_sym)):
node_tem = all_sym[i]
while node_tem != root:
if node_tem.check_num_of_child() == 1:
codes[i] = '0' + codes[i]
elif node_tem.check_num_of_child() == 2:
codes[i] = '1' + codes[i]
elif node_tem.check_num_of_child() == 3:
codes[i] = '2' + codes[i]
elif node_tem.check_num_of_child() == 4:
codes[i] = '3' + codes[i]
else:
codes[i] = '4' + codes[i]
node_tem = node_tem.father
print(codes)
return codes def Get_All_Symbol(self,Q,N,R,sp):
all_sym = []
symbol_sequence = []
nodes = []
for i in range(N):
symbol_sequence.append(0)
for i in range(pow(Q,N)):
j = N-1
P = sp[symbol_sequence[0]]
for k in range(N):
if k != 0:
P *= sp[symbol_sequence[k]]
if R == 2:
all_sym.append(Node_2(P))
elif R == 3:
all_sym.append(Node_3(P))
elif R == 4:
all_sym.append(Node_4(P))
elif R == 5:
all_sym.append(Node_5(P)) while symbol_sequence[j] == Q-1:
symbol_sequence[j] = 0
j -= 1
if j == -1:
# print(len(all_sym))
if( int((Q - R)/(R - 1))!=(Q - R)/(R - 1) ):
Q_expand = int((Q - R)/(R - 1)+1)*(R - 1)+R
for i in range(Q_expand - Q):
if R == 2:
all_sym.append(Node_2(0))
elif R == 3:
all_sym.append(Node_3(0))
elif R == 4:
all_sym.append(Node_4(0))
elif R == 5:
all_sym.append(Node_5(0))
return all_sym
symbol_sequence[j] += 1 def Read_Input(self):
Q = int(self.lineEdit_5.text()) # num of symbol
N = int(self.lineEdit_6.text()) # num of sequence
R = int(self.lineEdit_7.text()) # num of radix
text = self.textEdit.toPlainText()
sp = self.Get_Symbol_Probability(text) # symbol probability
if Q<8 or Q>15 or N<1 or N>3 or R<2 or R>5 or len(sp)!=Q or sum(sp)<0.99999:
# self.ui_error.show()
# print(sum(sp))
return 0,0,0,0
else:
# print(Q,N,R,sp)
return Q,N,R,sp def Str_Find_HH(self,str): # HH:huan hang '\n'
n = len(str)
pos = list()
for i in range(n):
if str[i] == '\n':
pos.append(i)
# print(pos)
return pos def Get_Symbol_Probability(self,str):
n = len(str)
pos = self.Str_Find_HH(str)
sp = list()
n_pos = len(pos)
for i in range(n_pos):
if i == 0:
sp.append(float(str[0:pos[i]]))
else:
sp.append(float(str[pos[i - 1] + 1:pos[i]]))
# print(sp)
return sp def Calculate_Performance_Index(self,N,R,sp,all_sym,codes):
HU = 0
l_avr = 0
for i in range(len(sp)):
HU += -sp[i]*math.log2(sp[i])
for i in range(len(all_sym)):
l_avr += all_sym[i].P*len(codes[i])
effi = HU*N/l_avr/math.log2(R) self.lineEdit_2.setText(str(round(HU,5)))
self.lineEdit_3.setText(str(round(l_avr,2)))
self.lineEdit_4.setText(str(round(effi*100,4))+'%')

费诺编码:

    def Feno_Coding(self):
Q,sp = self.Read_Input()
if Q == 0 and sp == 0:
self.ui_error.show()
return
sp_node = [] self.feno_code = ['']*len(sp)
sp.sort(reverse=True) for i in range(len(sp)):
sp_node.append(Node(sp[i],i))
self.Coding(sp_node)
# print(self.feno_code)
outcome = ''
for i in range(len(sp)):
outcome = outcome + str(sp[i]) + ' ' + self.feno_code[i] + ' ' + '\n'
self.textEdit_2.setPlainText(outcome)
self.Calculate_Performance_Index(sp,self.feno_code) def Coding(self,sp_node):
if len(sp_node) == 1:
return
findPos = 0
diff_c = 1
sum1 = 0
sum2 = 0
left_flag = 0 # 0 means left bigger than right for i in range(len(sp_node)-1):
for j in range(i+1):
sum1 += sp_node[j].P
for k in range(i+1,len(sp_node)):
sum2 += sp_node[k].P
if abs(sum1-sum2) < diff_c:
diff_c = abs(sum1-sum2)
if sum1 < sum2:
left_flag = 1
else:
left_flag = 0
findPos = i
sum1 = 0
sum2 = 0 for i in range(len(sp_node)):
if left_flag:
if i <= findPos:
self.feno_code[sp_node[i].pos] += '1'
else:
self.feno_code[sp_node[i].pos] += '0'
else:
if i <= findPos:
self.feno_code[sp_node[i].pos] += '0'
else:
self.feno_code[sp_node[i].pos] += '1' left = []
right = []
for i in range(findPos+1):
left.append(sp_node[i])
for i in range(findPos+1,len(sp_node)):
right.append(sp_node[i]) self.Coding(left)
self.Coding(right) def Read_Input(self):
Q = int(self.lineEdit.text()) # num of symbol
text = self.textEdit.toPlainText()
sp = self.Get_Symbol_Probability(text) # symbol probability
if Q<10 or len(sp)!=Q or sum(sp)<0.99999:
# self.ui_error.show()
# print(sum(sp))
return 0,0,0,0
else:
# print(Q,N,R,sp)
return Q,sp def Str_Find_HH(self,str): # HH:huan hang '\n'
n = len(str)
pos = list()
for i in range(n):
if str[i] == '\n':
pos.append(i)
# print(pos)
return pos def Get_Symbol_Probability(self,str):
n = len(str)
pos = self.Str_Find_HH(str)
sp = list()
n_pos = len(pos)
for i in range(n_pos):
if i == 0:
sp.append(float(str[0:pos[i]]))
else:
sp.append(float(str[pos[i - 1] + 1:pos[i]]))
# print(sp)
return sp def Calculate_Performance_Index(self,sp,codes):
HU = 0
l_avr = 0
for i in range(len(sp)):
HU += -sp[i]*math.log2(sp[i])
for i in range(len(sp)):
l_avr += sp[i]*len(codes[i])
effi = HU/l_avr/math.log2(2) self.lineEdit_2.setText(str(round(HU,5)))
self.lineEdit_3.setText(str(round(l_avr,2)))
self.lineEdit_4.setText(str(round(effi*100,4))+'%')

香农编码:

   def Shannon_Coding(self):
Q,sp = self.Read_Input()
if Q == 0 and sp == 0:
self.ui_error.show()
return shannon_code = ['']*len(sp)
sp.sort(reverse=True)
for i in range(len(sp)):
P_acc = 0
code = ''
l = int(-math.log2(sp[i])+1)
for j in range(i):
P_acc += sp[j]
while True:
P_acc *= 2
if P_acc >= 1:
code += '1'
else:
code += '0'
if len(code) == l:
break
P_acc -= int(P_acc)
if P_acc == 0:
if(len(code)<l):
code += '0'*(l-len(code))
break
shannon_code[i] = code[:l]
# print(shannon_code) outcome = ''
for i in range(len(sp)):
outcome = outcome + str(sp[i]) + ' ' + shannon_code[i] + ' ' + '\n'
self.textEdit_2.setPlainText(outcome)
self.Calculate_Performance_Index(sp,shannon_code) def Read_Input(self):
Q = int(self.lineEdit.text()) # num of symbol
text = self.textEdit.toPlainText()
sp = self.Get_Symbol_Probability(text) # symbol probability
if Q<10 or len(sp)!=Q or sum(sp)<0.99999:
# self.ui_error.show()
# print(sum(sp))
return 0,0,0,0
else:
# print(Q,N,R,sp)
return Q,sp def Str_Find_HH(self,str): # HH:huan hang '\n'
n = len(str)
pos = list()
for i in range(n):
if str[i] == '\n':
pos.append(i)
# print(pos)
return pos def Get_Symbol_Probability(self,str):
n = len(str)
pos = self.Str_Find_HH(str)
sp = list()
n_pos = len(pos)
for i in range(n_pos):
if i == 0:
sp.append(float(str[0:pos[i]]))
else:
sp.append(float(str[pos[i - 1] + 1:pos[i]]))
# print(sp)
return sp def Calculate_Performance_Index(self,sp,codes):
HU = 0
l_avr = 0
for i in range(len(sp)):
HU += -sp[i]*math.log2(sp[i])
for i in range(len(sp)):
l_avr += sp[i]*len(codes[i])
effi = HU/l_avr/math.log2(2) self.lineEdit_2.setText(str(round(HU,5)))
self.lineEdit_3.setText(str(round(l_avr,2)))
self.lineEdit_4.setText(str(round(effi*100,4))+'%')

程序的入口:

import sys
import coding
from PyQt5 import QtCore, QtGui, QtWidgets if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = coding.Ui_MainWindow()
ui.setupUi(MainWindow) MainWindow.show()
sys.exit(app.exec_())

这里还附上完整的课程设计报告可供参考:









【python学习】PyQt基础学习以及一个信息论与编码课设实例的更多相关文章

  1. vagrant的学习 之 基础学习

    vagrant的学习 之 基础学习 本文根据慕课网的视频教程练习,感谢慕课网! 慕课的参考文档地址:https://github.com/apanly/mooc/tree/master/vagrant ...

  2. python 标准库基础学习之开发工具部分1学习

    #2个标准库模块放一起学习,这样减少占用地方和空间#标准库之compileall字节编译源文件import compileall,re,sys#作用是查找到python文件,并把它们编译成字节码表示, ...

  3. Python编程:基础学习常见错误整理

    # Python学习之错误整理: # 错误一:# TypeError: cannot concatenate 'str' and 'int' objects# 不能连接str和int对象age = 2 ...

  4. Spark (Python版) 零基础学习笔记(一)—— 快速入门

    由于Scala才刚刚开始学习,还是对python更为熟悉,因此在这记录一下自己的学习过程,主要内容来自于spark的官方帮助文档,这一节的地址为: http://spark.apache.org/do ...

  5. Python学习---线程基础学习

    线程基础 什么是线程(thread) 线程是CPU调度能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流[换言之,线程就是一堆指令集合], ...

  6. Python学习---Python的框架基础学习

    框架基础 框架实质: 所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端 B/S结构的响应: import socket def handle_requ ...

  7. Spark (Python版) 零基础学习笔记(二)—— Spark Transformations总结及举例

    1. map(func) 将func函数作用到数据集的每个元素,生成一个新的分布式的数据集并返回 >>> a = sc.parallelize(('a', 'b', 'c')) &g ...

  8. python+request 常用基础学习笔记

    1.pycharm,避免控制台输出的json内容中文出现乱码. #注:乱码为Unicode格式:\u6d4b\u8bd5.加入如下代码后正确返回中文:测试 get_result = r.json() ...

  9. [AngularJS学习笔记] 基础学习01

    2016-06-06开始学习AngularJS AngularJS是会extend HTML的 ng-directives 先学习了四个 ng-app:定义AngularJS Application的 ...

  10. 前端学习:html基础学习一

    1.HTML的语法(主要内容HTML语法格式.文档注释.代码格式) HTML的特点 1.可以设置文本的格式,比如标题.字号.文本颜色.段落等等 2.可以创建列表(例如打开百度,我们可以看到这样的列表) ...

随机推荐

  1. [编程基础] C++多线程入门1-创建线程的三种不同方式

    原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 1 创建线程的三种不 ...

  2. 2023牛客寒假算法基础集训营1 ACDEFGHKLM

    比赛链接 A 题解 知识点:模拟. 显然. (用char输入到一半直接给答案跳出,WA了两小时,无话可说. 时间复杂度 \(O(1)\) 空间复杂度 \(O(1)\) 代码 #include < ...

  3. prettier+ts+eslint+vscode配置代码保存自动格式化,自动remove unsed declaration,delete no-unused-imports

    每天都要开心(▽)哇: 以这个项目为案例 下面是项目的基本情况 What would you like to build? › App with Quasar CLI, let's go! Proje ...

  4. java 进阶P-2.3+P-2.4

    封闭的访问属性 private 封装:把数据和对数据的操作放在一起. (所谓封装就是把数据和对这些数据的操作放在一个地方,通过这些操作把这些数据保护起来,别人不能直接接触到这些数据) 1 privat ...

  5. 增加for循环-泛型的概念

    增加for循环 增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的.它的内部原理其实是个lterator迭代器,所以在遍历的过程中,不能对集 ...

  6. Rust Rand生成随机数

    # in project file cargo add rand extern crate rand; use rand::Rng; fn main() { let mut rng = rand::t ...

  7. DataGrid 设置某列可见或只读

    在ASP.NET中使用 DataGrid数据展示控件时,可以对数据进行展示,编辑,删除,在有些时候不希望某列被修改,进行如下设置 点击编辑后 想要如下效果  其中权限编码和权限分类不希望修改 设置方法 ...

  8. VMware虚拟机的简单安装和配置

    一.简单了解虚拟机 虚拟机英文名(Virtual Machine)是通过软件模拟的完整计算机系统.在实体计算机中能够完成的工作在虚拟机中都能够实现.在计算机中创建虚拟机时,需要将实体机的部分硬盘和内存 ...

  9. mybatis学习日记

    1.什么是框架 框架是软件开发中的一套解决方案,不同的框架解决不同的问题 2.三层架构 表现层:展示数据 业务层:处理业务需求 持久层:与数据库交互 3.持久层解决技术 JDBC技术(JDBC是一种规 ...

  10. Windows下x86和x64平台的Inline Hook介绍

    前言 我在之前研究文明6的联网机制并试图用Hook技术来拦截socket函数的时候,熟悉了简单的Inline Hook方法,但是由于之前的方法存在缺陷,所以进行了深入的研究,总结出了一些有关Windo ...