参考网上一些大佬的博客和各种学习网站,一路学习下来,总算弄懂了事件,信号槽的机制,这里总结一下自己的第一个实战程序,简易计算器,有兴趣的也可以来试试~
1.效果图
2.功能介绍:
能进行最基本的加减乘除运算
3.代码思路:
首先构思布局,这里在我的第三篇学习笔记中已经基本完成了布局,不重复叙述
其次对布局进行优化,如上面的单行文本编辑控件不可被直接编辑
再就是重头戏,如何进行计算,clear和back怎么实现,最初想到的是c语言学习时印象深刻的堆栈操作,后来发现了eval函数,考虑到只是一个很基本的练手计算器,变抛弃了堆栈的思路,简化了代码
eval本地测试如下:
注意这里b为float型
4.关键代码分析
第一段
def initUI(self):
self.string = ''#作为容器去计算
self.number = '0'#初始值
self.setWindowTitle('简单计算器')#设置标题
grid = QtWidgets.QGridLayout()#网格型布局
self.display = QtWidgets.QLineEdit('0')#QLineEdit是一个单行文本编辑控件。
'''
QLineEdit是一个单行文本编辑控件。
使用者可以通过很多函数,输入和编辑单行文本,比如撤销、恢复、剪切、粘贴以及拖放等。
通过改变QLineEdit的 echoMode() ,可以设置其属性,比如以密码的形式输入。
文本的长度可以由 maxLength() 限制,可以通过使用 validator() 或者 inputMask() 可以限制它只能输入数字。在对同一个QLineEdit的validator或者input mask进行转换时,最好先将它的validator或者input mask清除,以避免错误发生。
与QLineEdit相关的一个类是QTextEdit,它允许多行文字以及富文本编辑。
我们可以使用 setText() 或者 insert() 改变其中的文本,通过 text() 获得文本,通过 displayText() 获得显示的文本,使用 setSelection() 或者 selectAll() 选中文本,选中的文本可以通过cut()、copy()、paste()进行剪切、复制和粘贴,使用 setAlignment() 设置文本的位置。
文本改变时会发出 textChanged() 信号;如果不是由setText()造成文本的改变,那么会发出textEdit()信号;鼠标光标改变时会发出cursorPostionChanged()信号;当返回键或者回车键按下时,会发出returnPressed()信号。
当编辑结束,或者LineEdit失去了焦点,或者当返回/回车键按下时,editFinished()信号将会发出。
'''
self.display.setFont(QtGui.QFont("Times", 20))#设置字体
self.display.setReadOnly(True)#设置可编辑
self.display.setAlignment(QtCore.Qt.AlignRight)#设置文本位置,这里设置为右边开始
self.display.setMaxLength(15)#设置最大的长度
grid.addWidget(self.display,0,0,1,4)
'''
void QGridLayout::addWidget(QWidget * widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = 0)
6个参数表示控件名,行,列,占用行数,占用列数,对齐方式
'''
names = ['Clear', 'Back', '', 'Close',
'7', '8', '9', '/',
'4', '5', '6', '*',
'1', '2', '3', '-',
'0', '.', '=', '+']
pos = [(0, 0), (0, 1), (0, 2), (0, 3),
(1, 0), (1, 1), (1, 2), (1, 3),
(2, 0), (2, 1), (2, 2), (2, 3),
(3, 0), (3, 1), (3, 2), (3, 3 ),
(4, 0), (4, 1), (4, 2), (4, 3)]
c = 0
for name in names:
button = QtWidgets.QPushButton(name)
button.setFixedSize(QtCore.QSize(60,30))
button.clicked.connect(self.buttonClicked) # 给每个按钮设置信号/槽
if c == 2:
pass
#grid.addWidget(QtWidgets.QLabel(''), 0, 2) #替换 第三个按钮 为 文本标签!
else:
grid.addWidget(button, pos[c][0]+1, pos[c][1])
c = c + 1
self.setLayout(grid)
这里补充一个总结了QlineEdit的博客,点这里
这里了核心是对软件整体进行布局,并且设计了信号槽机制,为每个按钮都绑定了函数,并且设置了string和number为后面的计算服务
第二段
def buttonClicked(self):
#sender = self.sender(); # 确定信号发送者
#self.display.setText(sender.text())#确定text为name
text = self.sender().text()
if text == "=":
self.string = self.string+self.number
self.number = str(eval(self.string)) # 简单计算,这里使用eval直接计算字符串
self.string=''
elif text in '+-*/':
self.string = self.string+self.number+text
self.number='0'#清空数字
elif text == "Back":
self.string = self.string.Substring(0,self.string.Length - 1)#删去最后一位
elif text == "Clear":
self.number = "0"
elif text == "Close":
self.close()
else:
if(self.number == '0'):
self.number=''
self.number = self.number+text
self.display.setText(self.number)
这里对信号进行了处理,思路非常清晰,将number拼接到string上,当接受到=
时,对string进行eval计算,并重新清空等待下一轮输入
演示
源码已经放到github了,点这里,有任何问题欢迎留言一起探讨~
打包命令补充
pyinstaller -F --distpath relese -w --icon="F:\pythonexe\hello\image\1.ico" Ui_hello.py --noconsole