python3 pyQt5 启蒙入门 第1课 安装与运行

安装

  1. python 3.x
  2. qt5:pt有GPL版本的
  3. pyQt + SIP :python与qt5本来是两个独立的东西,为了将他们连接起来,所以使用中间件pyQt。但是,毕竟pyQt也是python的库,不能直接连接非python的组件,所以又需要sip来连接python与c、c++的组件。pyQt是GPL版本的,pySide是LGPL版本的。在安装sip的时候少了头文件qgeolocation.h,百度一片没用,还是谷歌后才找到的,头文件地址 https://github.com/RSATom/Qt/blob/master/qtlocation/src/positioning/qgeolocation.h

 

Qt的运行基本要包含两个部分:

  1. QApplication:用来进行事件循环
  2. QWidget:相当于控件,是所有控件的基类。特别的,如果QWidget没有parent对象(即不属于任何一个widget的child),那这个widget就是Window的角色(类似于winForm中的Form)。还有一个QWidgetLayout,可用来进行觉的布局,相当于android中的各种Layout,不同的是qt的widget可以自己就是一个AbsoluteLayout。当然,由于Button、LineEdit等也是Widget,所以自然也是可以给Button、LineEdit添加子Widget的(比如给LineEdit添加一个Label)。

看运行一个桌面程序最简单的代码:

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class Form(QWidget):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)

        nameLabel = QLabel("Name:")
        self.nameLine = QLineEdit()
        self.submitButton = QPushButton("&Submit")

        buttonLayout1 = QVBoxLayout()
        buttonLayout1.addWidget(nameLabel)
        buttonLayout1.addWidget(self.nameLine)
        buttonLayout1.addWidget(self.submitButton)

        self.submitButton.clicked.connect(self.submitContact)

        mainLayout = QGridLayout()
        # mainLayout.addWidget(nameLabel, 0, 0)
        mainLayout.addLayout(buttonLayout1,0,1)
        self.setLayout(mainLayout)
        self.setWindowTitle("Hello Qt")

    def submitContact(self):
        name = self.nameLine.text()

        if name == "":
            QMessageBox.information(self, "Empty Field", "Please enter a name and address.")
            return
        else:
            QMessageBox.information(self, "Success!","Hello %s!" % name)
            self.nameLine.setText("")

if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)

    screen = Form() #class Form(QWidget)
    screen.show()

    sys.exit(app.exec_())

 

从上面看到,widget的定位都是代码直接写的。有没有办法像winForm一样,通过拖拽的方式布局widget呢?答案是肯定的:使用qt的原生工具+pyQt提供的代码生成工具来完成。

  1. 使用qt的原生工具 Designer来拖拽生成布局文件 xxx.ui
  2. pyQt的工具pyuic(实际就是PyQt5.uic.pyuic模块,默认路径是/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/PyQt5/uic/pyuic.py)将根据xxx.ui文件生成python的xxx.py代码文件,代码文件里编写了布局widget的python代码
    # -*- coding: utf-8 -*-
    
    # Form implementation generated from reading ui file 'Dialog.ui'
    #
    # Created by: PyQt5 UI code generator 5.5.1
    #
    # 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(241, 130)
            self.label = QtWidgets.QLabel(Dialog)
            self.label.setGeometry(QtCore.QRect(30, 10, 171, 31))
            self.label.setObjectName("label")
            self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
            self.buttonBox.setGeometry(QtCore.QRect(20, 70, 164, 32))
            self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
            self.buttonBox.setObjectName("buttonBox")
    
            self.retranslateUi(Dialog)
            self.buttonBox.accepted.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", "Hello World!"))
    

     

布局代码是生成了,但是怎么样才能使用这个生成的文件呢?

直接获得Ui_Dialog的实例?不行,Ui_Dialog的基类是object,没有QWidget,不能show,不能作为窗体。

那有两种方式来使用生成的布局类:

  1. 布局是在setupUi方法里进行的,它的参数(方法声明的第2个参数)就是一个Widget实例。有没有熟悉的感觉?对,decorator。既然如此,就这样写:
    class About(QWidget, Dialog.Ui_Dialog):
       def __init__(self):
            super(QWidget, self).__init__()
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        win = About()
        decorator = Dialog.Ui_Dialog()
        decorator.setupUi(win)
        win.show()
    
        sys.exit(app.exec())

     

  2. 方式1虽然也可以,但是必须将decorator保存在About的私有变量中,才能引用decorator里的控件,自定义的窗口和decorator相互有引用,混乱不堪。那怎么办呢?既然Ui_Dialog没有继承自QWidget才不能直接使用,那把让About继承QWidget总行了吧?Good!
    from PyQt5.QtWidgets import *;
    from PyQt5.QtCore import *;
    import sys;
    import Dialog;
    
    
    class About(QWidget, Dialog.Ui_Dialog):
    
        def __init__(self):
            super(QWidget, self).__init__()
            self.setupUi(self) #布局
    
        def accept(self):
            self.label.setText("clicked")
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        win = About()
        win.show()
    
        sys.exit(app.exec())

    哈哈,多继承还是强大啊!

到此,一个基于Qt5的python桌面程序就跑起来了,欢呼吧!

1

 

One thought on “python3 pyQt5 启蒙入门 第1课 安装与运行

发表评论

电子邮件地址不会被公开。