【Qt】初识QT

3 篇文章 0 订阅


本文主要记录初识QT过程中遇到的一些问题。

安装–MAC+QT5+Pycharm

系统环境

系统MacOS10.13.6; python3.6; IDE:pycharm.

软件

QT:直接去官网安装 Qt5.8.0完整安装包免费版(非commercial),傻瓜式安装,不要自行安装 QtCreator 或之前的版本等。
PyQt:一个 Python 插件,也可以简单理解为一座桥,连接 Pycharm 和 Qt。
PyCharm:已经装好的常用IDE,要做的就是把 PyQt 这个工具包插入到 PyCharm 里面去。

安装过程

1.装QT

有两种方法装QT:

  • 方法一:直接去Qt官网下载安装,先做一些简单问题回答,选OpenSources系列的,下载界面自动根据系统选择下载文件,下载后打开运行安装就行。据说需要先装Xcode,没Xcode装不上QT,我原来就装过Xcode,所以直接开始安装的,安装过程中有提示需要更新某些版本的Xcode,将会自动下载,我一路点OK就完事了。最后选择组件之后就开始下载安装了,我貌似是组件选多了,提示安装后将占用7.15G磁盘空间…接下来就是漫长的等待了,大概…。
  • 方法二:网上说也可以选择使用 brew。terminal里一句话搞定:
    $brew install qt
2.装pyqt5

pyqt5也有好几种装法:

  • brew 安装:这个方法要先装好brew(我已经装过了),打开 Terminal ,输入这两条指令,$brew install sip$brew install pyqt。如果成功安装 Qt5 ,那么会默认安装 PyQt5。一般来说brew 安装完毕,系统就会自动找到PyQt5,但如果安装路径或者环境变量有问题,系统找不到PyQt5,那就换下面几种办法吧。
  • pycharm安装:打开pycharm->preferences->project interpreter->选择要连接的python解释器(我装在python3.6上的)->点左下角加号->搜索框中输入PyQt5->选中要装的包->install package。【试了下,没搜到pyqt5,只看到了pyqt5-tools之类的,点pyqt5-tools包安装提示找不到,放弃!所以我是用pip装上的】
  • pip安装:提前装好了pip,打开 Terminal,一句话搞定,pip3 install pyqt5。(我电脑上装的python2和python3都有,所以配置的给python3安装要用pip3哈,如果电脑上只有一个python或者配置好了pip指令就给python3装,输入pip install pyqt5就行)。
3.配置 QtDesigner

这一步是将 PyQt 加入 PyCharm 中,最重要的一趴!!!

插点题外话,前面装pyqt5我是分分钟搞定的,装完之后先跑了个小窗口程序确认装好了,能用了,但是,找不到传说中的QtDesinger!而我需要的就是在PyCharm里面调用QtDesinger(QtDesigner是Qt里面的一部分),QtDesinger里面拖动图标做图,输出一个.ui文件,然后通过 PyQt 插件中转化成.py文件,进行后续的调试以及和其他程序模块互联。
于是就开始纠结QtDesinger的问题了,时间也主要花在了这一部分上。我一直以为我还需要安装一个QtDesigner,其实QtDesigner是Qt里面的一部分,装好Qt之后在它的安装目录里就能找到QtDesigner.app,记下它的路径,配置的时候用得到。

先上个参考资料,参照Python - Mac下PyCharm&PyQt5环境搭建
QtDesigner是个Qt的界面可视化工具,可以很方便的设计UI,所见即所得。网上说Designer的位置在Qt-5.5.1/5.5/clang_64/bin/Designer.app,可以在PyCharm中配置Designer的路径,这样就可以在PyCharm中快速启动Designer了。

下面是配置方法:

  • 打开pycharm的设置,快捷键是command+,
  • 找到Tools -> External Tools
  • 点击 + -> Create Tool
  • 按下图配置
4.配置 PyUIC

这个工具是用来把用Qt Designer生成的ui文件转换成py文件的,是一个命令行工具。
方法如下:

  • 打开pycharm的设置,快捷键是command+,
  • 找到Tools -> External Tools
  • 点击 + -> Create Tool
  • 按下图配置

其中name是你将来会在tool里看到的名字,只要以后认得,可以随便写,一般都写PyUIC;
Program选你所用的python编译器的地址下的pyuic5,我的地址是:

Parameters是:
-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.
working directory是:
$ProjectFileDir$
配置完点OK就完事了,这时候在Tools -> External Tools里就能看到刚添加的两个小工具啦,在右键菜单中的tools里也可以看到。


上手–使用方法简介

使用PyQt5的第一个GUI App:Getting started with PyQt5
有两种方法用python实现GUI,但实际使用时基本都用第二种,第一种。。。呵呵,鬼才要自己写ui代码呢╭(╯^╰)╮

  • 方法一:直接写.py文件
    这只是一个理论方法,一般只用来熟悉、了解大概的ui化过程,以及,测试一下自己电脑上PyQt5装好了没有。
    类似下面,直接建一个.py文件,然后就开写了。窗口大小之类的信息,事无巨细的全部要自己通过参数设置,想想就让人崩溃。而且设计出的界面都比较简单,无法满足实际应用的需求。
# -*- coding: utf-8 -*- 
import sys 
from PyQt5.QtWidgets import QApplication, QWidget 
app= QApplication(sys.argv) 
window= QWidget() 
window.resize(550, 150) 
window.show() 
app.exec_()

事实上,我们很少自己写 ui 的 py 文件,一般采用下面的方法二.

  • 方法二:使用 QtDesigner 将 .ui 转换为 .py
    使用 QtDesigner 直接绘制 ui 图,然后再使用转换器将 ui 图直接生成 py 文件。这种方法更推荐,用起来也更方便快捷。
    用QtDesigner画完ui 图后,保存为xx.ui文件,在Pycharm中项目文件中选择xx.ui,右键选择外部工具–>PyUIC,生成py源文件ui_xx.py。这样ui部分代码就完成啦。
    当然,现在的代码还只有一个界面的类,还需要在主函数中实例化才能显示出来。即使实例化后显示出来,也仅仅是个界面,无法对用户的操作做出响应,因为没有添加逻辑代码。
    我们可以继续在此文件中添加逻辑代码,让界面“动起来”;也可以新建一个文件专门来写逻辑代码,通过signal & slot连接界面和逻辑,让界面“思路清晰的高级的动起来”。
    下面介绍的信号与槽的概念会解释:界面是如何“思路清晰”,如何“高级的动起来”的~~

框架–signal & slot,让界面与和逻辑分离

概念

下面是科普性的信号和槽的概念,from PyQt - Signals & Slots

Unlike a console mode application, which is executed in a sequential manner, a GUI based application is event driven. Functions or methods are executed in response to user’s actions like clicking on a button, selecting an item from a collection or a mouse click etc., called events.
不像控制台上执行有序指令的应用,GUI应用是事件驱动的。响应用户的点击某个按钮、在集合中选择某个选项、点击鼠标等操作时执行的函数或者方法,这就叫事件。
Widgets used to build the GUI interface act as the source of such events. Each PyQt widget, which is derived from QObject class, is designed to emit ‘signal’ in response to one or more events. The signal on its own does not perform any action. Instead, it is ‘connected’ to a ‘slot’. The slot can be any callable Python function.
部件是作为事件的源,用来建立GUI交互动作的。每个被QObject类驱动的Pyqt部件,都是用来触发一个或多个事件响应的信号。信号本身不做任何响应。信号连接到一个槽,这个槽可以是任何可调用的python函数。
In PyQt, connection between a signal and a slot can be achieved in different ways. Following are most commonly used techniques −
在Pyqt里,信号和槽之间的连接有不同的方式实现,下面是最常用的技巧:
QtCore.QObject.connect(widget, QtCore.SIGNAL(‘signalname’), slot_function)
A more convenient way to call a slot_function, when a signal is emitted by a widget is as follows −
当一个信号被一个部件widget触发,下面是一个更方便的方式来调用一个slot_function槽函数:
widget.signal.connect(slot_function)
Suppose if a function is to be called when a button is clicked. Here, the clicked signal is to be connected to a callable function. It can be achieved in any of the following two techniques −
假设当一个按钮被点击时一个函数被调用了。这里,一个点击信号被连接到一个可调用函数,这个连接能通过下面两种方式实现:
QtCore.QObject.connect(button, QtCore.SIGNAL(“clicked()”), slot_function)
or
button.clicked.connect(slot_function)

自己的理解

  • GUI:窗口应用程序,主要包括界面和逻辑两部分;
  • ui:窗口布局,也就是界面,包括窗口里放了些啥控件,各控件长什么样,放在什么位置等信息;
  • widget:控件/部件,窗口上所有可见和不可见的用来跟用户交互的东西都是控件,比如按钮、文本框、滑动条之类的都是widget;
  • signal:信号,用户在widget上动作产生信号,比如用鼠标点击了一下某个按钮就会触发一个点击按钮的信号,每个widget都可能触发多种不同的信号;
  • slot:槽,每个信号都有一个槽与之相连,槽里面是用来放可调用的函数名的,当某个signal被触发,与之相连的槽里的函数就被调用执行一次;当然,槽里也可以是空的,那就是对这个信号不响应,不执行任何程序,直观感受就是操作了没反应咯。
  • 分离:通过信号与槽的连接关系可以将GUI的界面代码和逻辑代码分开,可以使得各模块的逻辑功能与流程更清晰,并且在调整任何一个单一模块时,减少模块间干扰。也就是对界面和逻辑去耦合
  • 为什么要去耦合:实际应用过程中,界面上可能会经常需要修修改改,比如说某个控件挪一下位置,就要重新生成一个ui_xx.py文件,如果把逻辑代码也写在这个文件里,那每次生成一次ui_xx.py就需要重新添加整理一次逻辑代码,费时费力,非常不方便。而如果ui_xx.py只用来写界面代码,不包含任何逻辑处理,新建一个xx.py来专门放槽函数逻辑,这样每次修改完ui界面后直接生成新的ui_xx.py覆盖改动前的ui文件就行,槽函数文件只管理逻辑代码,ui文件只表现界面代码,这样逻辑与界面分而治之,用起来就很方便。优点们在下面~

优点

  • 界面与逻辑互不干扰,易于管理代码;
  • 使得.ui文件通过外部工具pyuic直接转化为.py文件时,避免重复工作;
  • 响应事件操作的逻辑清晰明了;
  • 代码结构清晰明了,且易读。

操作

写一个GUI大概可分为以下几个步骤:

1. 设计ui

打开pycharm,建好工程,找到菜单栏Tools -> External Tools ->QtDesigner,通过pycharm打开QtDesigner。用QTdesigner通过拖拽控件的方式排好界面布局,保存为一个xx.ui文件,放在工程文件夹里。

2. 转换成py

回到pycharm,工程文件里选中刚保存的xx.ui,右键选择外部工具->PyUIC,py源文件ui_xx.py就出现在项目文件里啦。

3. 新建槽函数的py文件

在项目中新建文件xx.py,创建类MainWindow类,在这里去绑定相应的signal和slot,实现逻辑代码,这样代码结构也清晰多了,以后如果再遇到ui更新,我们只需将更新的ui文件替换并生成新的ui_xx.py,这样就实现了ui和逻辑的分离。
代码如下:

from PyQt5 import QtCore, QtGui, QtWidgets
from ui_mainwindow import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.Title.setText("hello Python")
        #这里可理解为signal与slot的连接
        #signal是用户对控件World的click操作触发的
        #slot是下面的onWorldClicked函数,这里只填函数名
        self.World.clicked.connect(self.onWorldClicked)
        #同上,China.clicked信号连接到槽函数onChinaClicked()
        self.China.clicked.connect(self.onChinaClicked)
        #同上,lineEdit.textChanged信号连接到槽函数onlineEditTextChanged()
        self.lineEdit.textChanged.connect(self.onlineEditTextChanged)
        
    #World.clicked信号的slot function的实现,函数内容就是响应内容
def onWorldClicked(self, remark):
        print(remark)
        self.Title.setText("Hello World")
    #同上,China.clicked信号的响应内容
def onChinaClicked(self):
        self.Title.setText("Hello China")
    #同上,lineEdit.textChanged信号的响应内容
def onlineEditTextChanged(self,p_str):
        self.Title.setText(p_str)
4. main函数中调用

再新建一个主函数main.py,在主函数里实例化上一步创建的类MainWindow,并调用show方法显示出来。

from PyQt5 import QtCore, QtGui, QtWidgets 
from mainwindow import MainWindow 
import sys 

if __name__== "__main__": 
app= QtWidgets.QApplication(sys.argv) 
mainWindow= MainWindow() 
    mainWindow.show() 
    sys.exit(app.exec_())

自己总结的通用代码框架

以上的操作可以总结为三大步:

  1. 设计ui,xx.ui转换成 ui_xx.py;
  2. 实现逻辑功能,xx.py;
  3. main函数中实例化,main.py
    其中第2步和第3步可以总结出通用代码,如下:
1. signal connect to slot
# -*- coding: utf-8 -*-
# !/usr/bin/python3
# file name: xx.py
from PyQt5 import QtCore, QtGui, QtWidgets
from ui_xx import Ui_MainWindow #ui_xx替换成ui文件的文件名
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        #添加若干个signal与slot的连接,格式如下
        widget.signal.connect(slot_function)
    #添加若干个槽函数,格式如下
def slot_function(self, args):
        pass
2. realize in main()
# -*- coding: utf-8 -*-
# file name: main.py
from PyQt5 import QtCore, QtGui, QtWidgets 
from xx import MainWindow   #xx替换成上面xx.py的文件名
import sys 

if __name__== "__main__": 
app= QtWidgets.QApplication(sys.argv) 
mainWindow= MainWindow() 
    mainWindow.show() 
    sys.exit(app.exec_())

参考链接

https://www.jianshu.com/p/caef389055d5
https://blog.csdn.net/yizhou2010/article/details/63252704
http://gavinliu.cn/2016/01/17/Python-Mac下PyCharm-PyQt5环境搭建/


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值