pyqt5必须和python对应_pyqt5 中文教程及Python程序打包成exe

一、创建自己的第一个GUI界面

成果图:

Snap12.png

这时所有按钮都无效果,但是退出按钮可以正常工作。

代码如下:

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数据库,就可以看到结果了。

Snap108.png

三、查看数据库

我们在创建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,下次程序重新开启之后,点击“浏览数据”按钮,啥都没有,只能在新建数据之后才能浏览。

Snap109.png

四、添加和删除数据

继续写两个函数。

# 添加一行数据行

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

Snap13.png

就会在当前文件下形成build文件夹、dist文件夹和.spec文件。dist里有一个ui.exe可执行文件。

Snap14.png

不过使用这种方法,其他的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,就可以正常运行了。

Snap110.png

小提示:

如果你不是用的anaconda,就需要到其他目录中去找,比如,有的platform文件夹位于D:\Qt\Qt5.4.0\5.4\msvc2013_64\plugins\platforms。