前言:从事C++开发一年时间,最近想学门新的语言,遂选择了最近比较热门的python。在网上简单了解了一下,最后决定从PyCharm、Pydev和Eric三种IDE中选择Eric作为目前的开发工具,本篇博客主要记录了配置开发环境的基本步骤、过程中所遇到的问题以及解决问题的方法。由于是安装完环境之后才开始写本篇文章,文章内如有错误之处还请见谅,同时欢迎指出问题。
一、开发环境配置(电脑是Windows 7系统):
1. 准备工作:开发环境主要包括Python、PyQt和Eric三个部分,目前Python已经更新到了3.6.5版本,不过看到网上说3.0以上版本有些地方兼容性不太好,所以最开始下载了2.7.9版本,结果安装Eric时发现官网只能下载到6.0以上的版本,并且下载的Eric安装包需要匹配Python 2.7.10以上的版本,无奈只能重新下载最新的Python 2.7.15 版本。
2. 下载安装包(附安装包下载地址):
(1)到Python官网下载python-2.7.15.amd64(电脑是64位的)安装程序,直接双击安装程序一路next即可,如果不想手动添加环境变量,记得安装过程中勾选Add python.exe to Path选项,如果安装成功,打开控制台窗口,输入python指令,会出现如下界面:
需要注意的是,通过此种方式添加环境变量,python的两个环境变量将位于Path变量值的最前面,会影响系统加载环境变量,此时在控制台窗口输入python命令会提示python不是内部或外部命令,将上述两个环境变量放到变量值的最后面即可,另外,楼主自己配置时,尝试将环境变量”G:\Python2.7\”改为”G:\Python2.7”,发现修改后同样会出现找不到环境变量的问题。
(2)看到网上有说安装PyQt需要先安装sip环境,所以同样下载了sip安装包,解压到Python安装路径下的site-packages文件夹下(这里是G:\Python2.7\Lib\site-packages
),进入sip文件夹中按shift键并单击鼠标右键打开控制台窗口,输入configure.py即可完成安装。
(3)下载PyQt的exe安装程序,直接next即可完成安装,正常情况下程序会自动安装到site-packages文件夹下,安装后的目录结构如下图所示。
(4)安装Eric软件,目前官网只能下载到最新版本,楼主自己找了好久也没发现旧版本的下载链接,这也是之前提到重新安装Python 2.7.15的原因。下载好之后解压到任意位置并进入文件夹内下双击运行install.py文件,会弹出控制台窗口完成安装过程,然后进入Python文件夹下找到eric6.bat文件,双击运行就可以打开Eric软件,这时候看到的是配置界面,可以进行简单的配置。
首先导入api文件,依次点击Editor->APIs->选择语言和工程类型->Add file installed APIs->Compile APIs,等待一段时间后点击OK即可,界面如下图所示。
接着可以配置一下代码自动补全功能,点击Editor->Autocompletion,General选项下的4个选项全部勾选,界面如下图所示。
(5)备注一下Eric软件的打开位置:
(6)下面附安装包的下载地址:
Python下载地址:https://www.python.org/downloads/
Sip下载地址:https://sourceforge.net/projects/pyqt/files/sip/
PyQt下载地址:https://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.11.4
Eric下载地址:https://sourceforge.net/projects/eric-ide/files/
二、编写简单的python脚本程序:
1.程序功能:一个使用QPushButton和QLineEdit控件的Gui程序,点击不同的QPushButton,QLineEdit对应显示不同的提示内容,界面如下图所示。
2.程序功能实现:
创建工程:打开Eric软件,依次点击工具栏的Project->New选项,进入下图所示界面,输入工程名,选择配置,点击OK
这时候会看到一个空白的__init__.py文件
不用管它,点击红框标出的图标
在上图的空白区域单击鼠标右键,选择New Form
gui窗口类型选择QWidget,点击OK,输入文件名hello,进入Qt设计师界面
从左侧控件栏拖拽Push Button和Line Edit控件到空白区域
修改控件名称和显示内容,此处跳过界面布局步骤,因为不影响功能实现(此处还使用了Group Box控件)
保存并关闭界面,回到Eric软件,目录下多了hello.ui文件
右击它选择compile form,点击上图的红框标注图标,发现多了一个Ui_hello.py文件
点击工具栏的Start->Run Script可以运行脚本,弹出界面,但是按钮点击没有反应,应该还没有实现功能,回到hello.ui文件,右击选择Generate Dialog Code生成对话框代码
输入文件名,将4个按钮的clicked信号都勾选上,便于实现功能(实际上可以不勾选,只要定义槽函数时名称对应上就可以),点击OK后会生成hello.py文件,其中可以很方便的实现信号槽连接
生成的脚本程序有两个错误导致无法运行,一个是Ui_hello前的“.”得去掉,另一个是需要手动添加最下面的一段代码,其作用是给脚本程序指定入口
上图所示的是槽函数的实现,其中我又增加了自定义的一个信号和槽函数,如下图所示
图中红色方框标出的分别是信号和槽的定义,椭圆形标注的是信号槽的连接,绿色方框内是增加延时和发射信号,不过运行时点击第一个按钮的实际效果是延时500ms后两个LineEdit同时显示内容,和期望的先后显示不一样,暂时还不清楚是什么机制导致的,下面贴上运行结果图
3.注意事项和可能遇到的问题:
(1)通常代码的最前面几行是指定编码格式和加载的模块库等内容,使用PyQt最常用的是QtCore和QtGui模块,下图是常用的两种导入方法,
比如说,如果只导入QtCore模块,调用QThread类时运行会报错。
(2)建立工程时选择工程类型需要注意,比如我安装的是PyQt4版本,如果选择了PyQt5Gui类型,那么将无法通过ui文件生成对话框代码,提示错误内容是ui文件不在当前文件路径下。
(3)ui文件生成的py文件最好不要手动修改,不熟悉情况下改动会造成各种错误,并且重新生成py文件时会覆盖之前的修改内容。
(4)第一次生成对话框代码时基本会记得手动添加最后一段代码,以后可能会忘记,这种情况下运行结果不会出现错误,但同样不会出现界面。
(5)使用信号槽需要导入QtCore模块,但不同的导入方法对应不同的信号连接和使用方式,具体的这里就不多说了,可以自己多尝试尝试。
三、这里附上两个python文件的代码(我自己定义的文件名是button):
1.Ui_button.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'G:\working\Project_PyQt\LoadUI\button.ui'
# Created by: PyQt4 UI code generator 4.11.4
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName(_fromUtf8("Form"))
Form.resize(212, 194)
self.verticalLayout_4 = QtGui.QVBoxLayout(Form)
self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4"))
self.verticalLayout_2 = QtGui.QVBoxLayout()
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.groupBox = QtGui.QGroupBox(Form)
self.groupBox.setObjectName(_fromUtf8("groupBox"))
self.horizontalLayout_3 = QtGui.QHBoxLayout(self.groupBox)
self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3"))
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.pushButton_1 = QtGui.QPushButton(self.groupBox)
self.pushButton_1.setObjectName(_fromUtf8("pushButton_1"))
self.horizontalLayout.addWidget(self.pushButton_1)
self.pushButton_2 = QtGui.QPushButton(self.groupBox)
self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
self.horizontalLayout.addWidget(self.pushButton_2)
self.verticalLayout.addLayout(self.horizontalLayout)
self.horizontalLayout_5 = QtGui.QHBoxLayout()
self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5"))
self.pushButton_3 = QtGui.QPushButton(self.groupBox)
self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
self.horizontalLayout_5.addWidget(self.pushButton_3)
self.pushButton_4 = QtGui.QPushButton(self.groupBox)
self.pushButton_4.setObjectName(_fromUtf8("pushButton_4"))
self.horizontalLayout_5.addWidget(self.pushButton_4)
self.verticalLayout.addLayout(self.horizontalLayout_5)
self.horizontalLayout_3.addLayout(self.verticalLayout)
self.verticalLayout_2.addWidget(self.groupBox)
self.groupBox_2 = QtGui.QGroupBox(Form)
self.groupBox_2.setObjectName(_fromUtf8("groupBox_2"))
self.verticalLayout_3 = QtGui.QVBoxLayout(self.groupBox_2)
self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
self.lineEdit = QtGui.QLineEdit(self.groupBox_2)
self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
self.verticalLayout_3.addWidget(self.lineEdit)
self.lineEdit_2 = QtGui.QLineEdit(self.groupBox_2)
self.lineEdit_2.setObjectName(_fromUtf8("lineEdit_2"))
self.verticalLayout_3.addWidget(self.lineEdit_2)
self.verticalLayout_2.addWidget(self.groupBox_2)
self.verticalLayout_4.addLayout(self.verticalLayout_2)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(_translate("Form", "Form", None))
self.groupBox.setTitle(_translate("Form", "Choose Button", None))
self.pushButton_1.setText(_translate("Form", "A", None))
self.pushButton_2.setText(_translate("Form", "B", None))
self.pushButton_3.setText(_translate("Form", "点右边", None))
self.pushButton_4.setText(_translate("Form", "不要点我", None))
self.groupBox_2.setTitle(_translate("Form", "Result", None))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Form = QtGui.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
2.button.py
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
#from PyQt4.QtCore import pyqtSignature
#from PyQt4.QtGui import QWidget
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from Ui_button import Ui_Form
class Form(QWidget, Ui_Form):
signal_A=QtCore.pyqtSignal()
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setupUi(self)
self.connect(self, QtCore.SIGNAL("signal_A()"), self.slot_A)
#使用装饰器将一个函数对象装饰为槽函数
@QtCore.pyqtSlot()
#@pyqtSignature("")
def on_pushButton_1_clicked(self):
self.lineEdit.setText('You clicked A')
QThread.msleep(500)
#发射信号
self.emit(QtCore.SIGNAL("signal_A()"))
@pyqtSignature("")
def on_pushButton_2_clicked(self):
self.lineEdit.setText('You clicked B')
@pyqtSignature("")
def on_pushButton_3_clicked(self):
self.lineEdit.setText('Click to the right')
@pyqtSignature("")
def on_pushButton_4_clicked(self):
self.lineEdit.setText('Do not click me!')
@QtCore.pyqtSlot()
def slot_A(self):
self.lineEdit_2.setText('enter slot_A')
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
form = Form()
form.show()
sys.exit(app.exec_())