一、创建自己的第一个GUI界面
成果图:
这时所有按钮都无效果,但是退出按钮可以正常工作。
代码如下:
from PyQt5 import QtGui,QtCore,QtWidgets,QtSql
from PyQt5.QtWidgets import QApplication, QWidget
import sys
'''
蜗牛博客 - pyqt5 中文教程
'''
class MainUi(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.initUi()
# 初始化UI界面
def initUi(self):
# 设置窗口标题
self.setWindowTitle("蜗牛博客 - pyqt5 中文教程")
# 设置窗口大小
self.resize(600,400)
# 创建一个窗口部件
self.widget = QtWidgets.QWidget()
# 创建一个网格布局
self.grid_layout = QtWidgets.QGridLayout()
# 设置窗口部件的布局为网格布局
self.widget.setLayout(self.grid_layout)
# 创建一个按钮组
self.group_box = QtWidgets.QGroupBox('数据库按钮')
self.group_box_layout = QtWidgets.QVBoxLayout()
self.group_box.setLayout(self.group_box_layout)
# 创建一个表格部件
self.table_widget = QtWidgets.QTableView()
# 将上述两个部件添加到网格布局中
self.grid_layout.addWidget(self.group_box,0,0)
self.grid_layout.addWidget(self.table_widget,0,1)
# 创建按钮组的按钮
self.b_create_db = QtWidgets.QPushButton("创建数据库")
# self.b_create_db.clicked.connect(self.create_db)
self.b_view_data = QtWidgets.QPushButton("浏览数据")
self.b_add_row = QtWidgets.QPushButton("添加一行")
self.b_delete_row = QtWidgets.QPushButton("删除一行")
self.b_close = QtWidgets.QPushButton("退出")
self.b_close.clicked.connect(self.close)
# 添加按钮到按钮组中
self.group_box_layout.addWidget(self.b_create_db)
self.group_box_layout.addWidget(self.b_view_data)
self.group_box_layout.addWidget(self.b_add_row)
self.group_box_layout.addWidget(self.b_delete_row)
self.group_box_layout.addWidget(self.b_close)
# 设置UI界面的核心部件
self.setCentralWidget(self.widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MainUi()
ex.show()
sys.exit(app.exec_())
说明:
class MainUi(QtWidgets.QMainWindow):这里的QtWidgets.QMainWindow表示该窗口的类型,这里是主窗口类型。所以设置成当QtWidgets.QMainWindow。你的窗口是一个会话框时你需要设置成:QtWidgets.QDialog。
app = QApplication(sys.argv)是实例化了一个应用程序对象QApplication(),在PyQt5中,每个应用程序都必须实例化一个QApplication(),如果没有这一行代码,则会出现“QWidget: Must construct a QApplication before a QWidget”的错误提示。
ex = MainUi()表示创建了一个MainUi()对象。
ex.show()使用QWidget对象的show()方法将创建的窗口显示出来。
sys.exit(app.exec_())表示调用应用程序对象的exec_()方法来运行程序的主循环,并使用sys.exit()方法确保程序能够完美的退出。
二、创建数据库功能
本来想使用Mysql数据库,可是我测试了一下,出现了以下的错误提示:
QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QODBC QODBC3
QSqlQuery::exec: database not open
QSqlQuery::exec: database not open
QSqlQuery::exec: database not open
QSqlQuery::exec: database not open
那就只好以Sqlite数据库为例。
在MainUi()类中,写一个创建数据库的函数create_db()
# 创建数据库
def create_db(self):
try:
# 调用输入框获取数据库名称
db_text, db_action = QtWidgets.QInputDialog.getText(self, '数据库名称', '请输入数据库名称',
QtWidgets.QLineEdit.Normal)
if (db_text.replace(' ', '') != '') and (db_action is True):
print(db_text)
self.db_name = db_text
# 添加一个sqlite数据库连接并打开
db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('{}.sqlite'.format(db_text))
db.open()
# 实例化一个查询对象
query = QtSql.QSqlQuery()
# 创建一个数据库表
query.exec_("create table zmister(ID int primary key, "
"site_name varchar(20), site_url varchar(100))")
# 插入三条数据
query.exec_("insert into zmister values(1000, '蜗牛博客', 'http://www.snailtoday.com')")
query.exec_("insert into zmister values(1001, '百度', 'http://www.baidu.com')")
query.exec_("insert into zmister values(1002, '腾讯', 'http://www.qq.com')")
print('创建数据库成功')
except Exception as e:
print(e)
然后通过下面这一行代码,将这个函数绑定到按钮上。
self.b_create_db.clicked.connect(self.create_db)
这样我们测试一下,然后用Navicat打开刚刚建立的Sqlite数据库,就可以看到结果了。
三、查看数据库
我们在创建UI界面的时候,在界面的右方放置了一个QTableView()部件,我们的数据库数据将显示在这上面。
# 浏览数据
def view_data(self):
# 实例化一个可编辑数据模型
self.model = QtSql.QSqlTableModel()
self.table_widget.setModel(self.model)
self.model.setTable('zmister') # 设置数据模型的数据表
self.model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange) # 允许字段更改
self.model.select() # 查询所有数据
# 设置表格头
self.model.setHeaderData(0,QtCore.Qt.Horizontal,'ID')
self.model.setHeaderData(1, QtCore.Qt.Horizontal, '站点名称')
self.model.setHeaderData(2, QtCore.Qt.Horizontal, '站点地址')
然后,将view_data()方法绑定在UI界面的【浏览数据】按钮的点击事件中
self.b_view_data.clicked.connect(self.view_data)
这样,创建数据之后,点击一下“浏览数据”按钮,就可以看到显示的数据。
不过这里有一个小bug,下次程序重新开启之后,点击“浏览数据”按钮,啥都没有,只能在新建数据之后才能浏览。
四、添加和删除数据
继续写两个函数。
# 添加一行数据行
def add_row_data(self):
# 如果存在实例化的数据模型对象
if self.model:
self.model.insertRows(self.model.rowCount(), 1)
else:
self.create_db()
# 删除一行数据
def del_row_data(self):
if self.model:
self.model.removeRow(self.table_widget.currentIndex().row())
else:
self.create_db()
然后将这两个方法分别绑定在【添加一行】和【删除一行】按钮的点击事件上:
self.b_add_row.clicked.connect(self.add_row_data)
self.b_delete_row.clicked.connect(self.del_row_data)
这样就可以实现添加、删除一行的功能了。
附最终的按钮代码:
self.b_create_db = QtWidgets.QPushButton("创建数据库")
self.b_create_db.clicked.connect(self.create_db)
self.b_view_data = QtWidgets.QPushButton("浏览数据")
self.b_view_data.clicked.connect(self.view_data)
self.b_add_row = QtWidgets.QPushButton("添加一行")
self.b_add_row.clicked.connect(self.add_row_data)
self.b_delete_row = QtWidgets.QPushButton("删除一行")
self.b_delete_row.clicked.connect(self.del_row_data)
五、python图形界面生成exe
下面我们将上面的程序打包成exe,能够在没有安装python的电脑上也能使用。
解决方案一:pyinstaller
要想将python程序打包成exe,需要pyinstaller和pywin32这两个包的支持。
使用pip install pyinstaller命令安装pyinstaller,另外安装pywin32前最好用pip list查看一下自己电脑上是否已经安装好了pywin32,如果没有的话,可以到这里下载,然后执行exe程序安装。
cmd进入到你的python文件所在的目录,假如你的文件为ui.py,执行以下代码:
pyinstaller --onefile --nowindowed ui.py
如果要加上icon的话:
pyinstaller --onefile --nowindowed --icon=" D:\Queena\PyCharmProjects\dist1\computer_three.ico" ui.py
就会在当前文件下形成build文件夹、dist文件夹和.spec文件。dist里有一个ui.exe可执行文件。
不过使用这种方法,其他的py文件生成的exe文件都可以执行,pyqt5的就不行。
而且后来在网上看别人说pyinstaller打包PyQT5开发的东西也不行。
没办法,办能另想办法。
解决方案二、使用py2exe
首先从这个网站下载py2exe,然后使用pip install py2exe-0.9.2.2-cp34-none-win_amd64.whl命令安装,没想到安装时出现如下的错误提示:py2exe-0.9.2.2-cp34-none-win_amd64.whl is not a supported wheel on this platform
没办法,我只好用conda create -n py34 python=3.4命令,新建立了一个py3.4的环境。
然后在ui.py文件所在目录建立了一个exe.py文件,代码如下:
from distutils.core import setup
import py2exe
import sys
#this allows to run it with a simple double click.
sys.argv.append('py2exe')
py2exe_options = {
"includes": ["sip"],
"dll_excludes": ["MSVCP90.dll",],
"compressed": 1,
"optimize": 2,
"ascii": 0,
"bundle_files": 1,
}
setup(
name = 'PyQt Demo',
version = '1.0',
windows = ['ui.py',],
zipfile = None,
options = {'py2exe': py2exe_options}
)
然后执行的时候又说没找到pyqt5,于是又安装pyqt5,结果安装pyqt5快完成时,又出现了如下的错误提示:
Could not find a version that satisfies the requirement sip>=4.19.1 (from PyQt) (from versions: )
o matching distribution found for sip>=4.19.1 (from PyQt5)。
在网上看了一下,有人遇到同样的问题,好像是py3.4用pip install pyqt5安装就会出错。
结果执行exe.py时,也出错。
Traceback (most recent call last):
File "exe.py", line 22, in options = {'py2exe': py2exe_options}
File "C:\ProgramData\Anaconda3\envs\py34\lib\distutils\core.py", line 148, in
setup
dist.run_commands()
File "C:\ProgramData\Anaconda3\envs\py34\lib\distutils\dist.py", line 955, in
run_commands
self.run_command(cmd)
File "C:\ProgramData\Anaconda3\envs\py34\lib\distutils\dist.py", line 974, in
run_command
cmd_obj.run()
File "C:\ProgramData\Anaconda3\envs\py34\lib\site-packages\py2exe\distutils_bu
ildexe.py", line 188, in run
self._run()
File "C:\ProgramData\Anaconda3\envs\py34\lib\site-packages\py2exe\distutils_bu
ildexe.py", line 267, in _run
builder.analyze()
File "C:\ProgramData\Anaconda3\envs\py34\lib\site-packages\py2exe\runtime.py",
line 164, in analyze
mf.import_hook(modname)
File "C:\ProgramData\Anaconda3\envs\py34\lib\site-packages\py2exe\mf3.py", lin
e 120, in import_hook
module = self._gcd_import(name)
File "C:\ProgramData\Anaconda3\envs\py34\lib\site-packages\py2exe\mf3.py", lin
e 274, in _gcd_import
return self._find_and_load(name)
File "C:\ProgramData\Anaconda3\envs\py34\lib\site-packages\py2exe\mf3.py", lin
e 337, in _find_and_load
raise ImportError(name)
ImportError: sip
虽然后来在网上找到安装sip的的方法,不过太麻烦了。
解决方案三、使用cx_Freeze
首先在你要打包的py文件的相同文件夹内,写一个exe.py文件
from cx_Freeze import setup, Executable
setup(name='test to exe',
version='0.1',
description='test from py file to exe file',
executables=[Executable("ui.py")]
)
然后cmd输入 python exe.py build命令,然后在相同目录中会生成一个bulid的目录,再进去exe.win-amd64-3.6目录,就会看到有一个ui.exe的文件。这时点击运行发发现如下的错误提示:
This application failed to start because it could not find or load the Qt platform plugin
这时需要将C:\ProgramData\Anaconda3\Library\plugins目录下的“platforms”这个文件夹copy到ui.exe所在的文件夹。然后再执行ui.exe,就可以正常运行了。
小提示:
如果你不是用的anaconda,就需要到其他目录中去找,比如,有的platform文件夹位于D:\Qt\Qt5.4.0\5.4\msvc2013_64\plugins\platforms。