为python名片夹项目制作用户界面(一):窗口弹出及保存名片
前言
名片夹项目是我自学python开始时做的第一个项目,当时依据视频及自己查资料,使其真正做到重复使用、记录名片的功能。但是没有用户界面还是不像一个应用工具,最近闲暇时间了解了一下python GUI 设计,经过对比多个库,决定使用pyqt5,一方面是功能强大,最主要的是网上相关文档多,适合自学。经过几天学习,第一阶段完成了页面弹出、将新建名片保存在txt文档中两个功能,特记录!
一、UI设计
UI是直接用QtDesigner画出来的,窗口按钮在designer里设置槽函数
其实在设计edit窗口的时候就觉得,完全可以在一个窗口里实现新建、修改、查看功能,但是没有在一个窗口里做,一方面是学习窗口跳转,另一方面觉得在一个窗口里实现,就像是一个小型的Excel了,没意思!
二、将UI文件转为python文件
使用终端命令pyuic5 -o D:\B.个人\python\edit.py D:\B.个人\python\edit.ui
可以将designer的UI文件转为python文件,也可以在pycharm里设置外部工具来实现。
导出的python文件如下
1、welcome.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(380, 163)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(29, 89, 321, 51))
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton_3 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.pushButton_3.setObjectName("pushButton_3")
self.horizontalLayout.addWidget(self.pushButton_3)
self.pushButton_2 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.pushButton_2.setObjectName("pushButton_2")
self.horizontalLayout.addWidget(self.pushButton_2)
self.pushButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(30, 10, 321, 16))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(30, 70, 321, 16))
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(self.centralwidget)
self.label_3.setGeometry(QtCore.QRect(40, 40, 291, 20))
font = QtGui.QFont()
font.setFamily("隶书")
font.setPointSize(16)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
self.pushButton_3.clicked.connect(MainWindow.open_new_ui)
self.pushButton_2.clicked.connect(MainWindow.open_edit_ui)
self.pushButton.clicked.connect(MainWindow.close)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton_3.setText(_translate("MainWindow", "新建"))
self.pushButton_2.setText(_translate("MainWindow", "查询"))
self.pushButton.setText(_translate("MainWindow", "关闭"))
self.label.setText(_translate("MainWindow", "**********************************************************************"))
self.label_2.setText(_translate("MainWindow", "**********************************************************************"))
self.label_3.setText(_translate("MainWindow", "欢迎使用名片管理系统,请选择您的操作"))
2、create.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'create_ui.ui'
#
# Created by: PyQt5 UI code generator 5.13.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(240, 146)
self.label = QtWidgets.QLabel(Dialog)
self.label.setGeometry(QtCore.QRect(30, 20, 41, 16))
font = QtGui.QFont()
font.setFamily("隶书")
font.setPointSize(16)
self.label.setFont(font)
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setGeometry(QtCore.QRect(30, 50, 41, 16))
font = QtGui.QFont()
font.setFamily("隶书")
font.setPointSize(16)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(Dialog)
self.label_3.setGeometry(QtCore.QRect(30, 80, 41, 16))
font = QtGui.QFont()
font.setFamily("隶书")
font.setPointSize(16)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.name_le = QtWidgets.QLineEdit(Dialog)
self.name_le.setGeometry(QtCore.QRect(80, 20, 113, 20))
self.name_le.setObjectName("name_le")
self.phone_le = QtWidgets.QLineEdit(Dialog)
self.phone_le.setGeometry(QtCore.QRect(80, 50, 113, 20))
self.phone_le.setObjectName("phone_le")
self.email_le = QtWidgets.QLineEdit(Dialog)
self.email_le.setGeometry(QtCore.QRect(80, 80, 113, 20))
self.email_le.setObjectName("email_le")
self.horizontalLayoutWidget = QtWidgets.QWidget(Dialog)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(30, 110, 171, 21))
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.ok_button = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.ok_button.setObjectName("ok_button")
self.horizontalLayout.addWidget(self.ok_button)
self.cancel_button = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.cancel_button.setObjectName("cancel_button")
self.horizontalLayout.addWidget(self.cancel_button)
self.retranslateUi(Dialog)
self.ok_button.clicked.connect(Dialog.create_new_card)
self.cancel_button.clicked.connect(Dialog.reject)
self.ok_button.clicked.connect(Dialog.accept)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.label.setText(_translate("Dialog", "姓名"))
self.label_2.setText(_translate("Dialog", "电话"))
self.label_3.setText(_translate("Dialog", "邮箱"))
self.ok_button.setText(_translate("Dialog", "确定"))
self.cancel_button.setText(_translate("Dialog", "取消"))
3、edit.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'edit_ui.ui'
#
# Created by: PyQt5 UI code generator 5.13.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(320, 240)
self.horizontalLayoutWidget = QtWidgets.QWidget(Dialog)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(20, 200, 281, 31))
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.edit = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.edit.setObjectName("edit")
self.horizontalLayout.addWidget(self.edit)
self.delet = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.delet.setObjectName("delet")
self.horizontalLayout.addWidget(self.delet)
self.back = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.back.setObjectName("back")
self.horizontalLayout.addWidget(self.back)
self.tableWidget = QtWidgets.QTableWidget(Dialog)
self.tableWidget.setEnabled(True)
self.tableWidget.setGeometry(QtCore.QRect(15, 10, 291, 192))
self.tableWidget.setMinimumSize(QtCore.QSize(291, 192))
self.tableWidget.setAlternatingRowColors(True)
self.tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.tableWidget.setTextElideMode(QtCore.Qt.ElideLeft)
self.tableWidget.setShowGrid(False)
self.tableWidget.setGridStyle(QtCore.Qt.DotLine)
self.tableWidget.setCornerButtonEnabled(True)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(3)
self.tableWidget.setRowCount(0)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(2, item)
self.tableWidget.verticalHeader().setDefaultSectionSize(22)
self.tableWidget.verticalHeader().setMinimumSectionSize(17)
self.retranslateUi(Dialog)
self.edit.clicked.connect(Dialog.save_all)
self.back.clicked.connect(Dialog.reject)
self.edit.clicked.connect(Dialog.accept)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.edit.setText(_translate("Dialog", "修改"))
self.delet.setText(_translate("Dialog", "删除"))
self.back.setText(_translate("Dialog", "返回"))
item = self.tableWidget.horizontalHeaderItem(0)
item.setText(_translate("Dialog", "姓名"))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(_translate("Dialog", "电话"))
item = self.tableWidget.horizontalHeaderItem(2)
item.setText(_translate("Dialog", "邮箱"))
三、调试各个窗口
我们可以看到UI转的python文件上方有一句warning:# WARNING! All changes made in this file will be lost!
我一开始没注意到,直接在窗口里写类函数,然后修改UI,重新生成py文件后这些函数又得重写,很烦,这才发现有这么一句警告,于是将函数写到了另外的文件里,UI文件单独放到resource文件夹内。
在每个窗口文件中,制作信号,将信号与designer里定义的槽函数连接起来。
1、welcome_window
from PyQt5.Qt import *
from resource.welcome_ui import Ui_MainWindow
class Welcome(QMainWindow, Ui_MainWindow):
show_create_pane_signel = pyqtSignal()
show_edit_pane_signal = pyqtSignal()
def __init__(self):
super().__init__()
self.setupUi(self)
def open_new_ui(self):
self.show_create_pane_signel.emit()
def open_edit_ui(self):
self.show_edit_pane_signal.emit()
if __name__ == "__main__":
import sys
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
window = Welcome()
window.show()
sys.exit(app.exec_())
2、create_window
from PyQt5.Qt import *
from resource.create_ui import Ui_Dialog
class Create(QDialog, Ui_Dialog):
create_card_singel = pyqtSignal(str,str,str)
def __init__(self):
super().__init__()
self.setupUi(self)
def create_new_card(self):
name = self.name_le.text()
phone = self.phone_le.text()
email = self.email_le.text()
self.create_card_singel.emit(name,phone,email)
if __name__ == '__main__':
import sys
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
window = Create()
window.create_card_singel.connect(lambda a,b,c: print(a,b,c))
window.show()
sys.exit(app.exec_())
3、edit_window
from PyQt5.Qt import *
from resource.edit_ui import Ui_Dialog
class Edit(QDialog, Ui_Dialog):
save_all_signal = pyqtSignal()
def __init__(self):
super().__init__()
self.setupUi(self)
def save_all(self):
print("名片已保存")
# card_content = self.columnView.text()
self.save_all_signal.emit()
if __name__ == '__main__':
import sys
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
window = Edit()
window.show()
sys.exit(app.exec_())
四、主程序
主程序中定义一个写txt文件的函数write_card,用来接收新建窗口点击确定时得到的三个内容,并以字典的格式存在card.txt文件中
#coding=utf-8
from welcome_window import Welcome
from create_window import Create
from edit_window import Edit
from PyQt5.Qt import *
def write_card(name,phone,email):
card_dic= {"name":name,"phone":phone,"email":email}
file_handle = open('card.txt', "a")
file_handle.write(str(card_dic))
file_handle.write('\n')
file_handle.close()
print('%s 名片已存入' % name)
if __name__ == "__main__":
import sys
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
welcome = Welcome()
create = Create()
edit = Edit()
welcome.show_create_pane_signel.connect(create.show)
welcome.show_edit_pane_signal.connect(edit.show)
create.create_card_singel.connect(lambda name,phone,email: write_card(name,phone,email))
welcome.show()
sys.exit(app.exec_())
目前做到这里,还差一个读取txt文件内容到edit窗口中,以及修改窗口数据后点击修改
按钮将文件更新的功能,这两天做完,发第二篇博文