电子产业一站式赋能平台

PCB联盟网

搜索
查看: 57|回复: 0
收起左侧

人生苦短,我用Python-手把手教你如何使用python写串口调试助手

[复制链接]

208

主题

208

帖子

1641

积分

三级会员

Rank: 3Rank: 3

积分
1641
发表于 2023-1-31 08:00:00 | 显示全部楼层 |阅读模式
绪论??笔者这里使用的是QTCreator和Python来实现一个简单的串口上位机的开发的简单过程,使用到Python,之前记录的Qt 使用C++ 写上位机也记录一篇文章,大家感兴趣的话可以看看。从零开始编写一个上位机(串口助手)QT Creator + C++
??这里我使用Python写上位机主要的原因就是Python强大的数据抓取能力以及数据处理能力,我们可以使用Python做上位机作为自动化测试工具,采集之后的数据整合都是 非常强大的,因为Python和C++都是高级语言,所以和前面叙述使用C++写上位机的流程有许多相似之处。唯一的差别就是想要使用QT 写上位机的话默认语言就是C++ 的,我们需要一个工具将QT设计的界面翻译成Python,后续就直接可以使用Python 引用我们使用QT设计的界面元素,对界面元素的数据处理以及数据交互实现控制。
??将C++转化成Python 目前主流的有PyQT和Pyside,至于PyQT5、PyQT6、Pyside2、Pyside6只是版本不同而已,至于两者的主要差别PyQT5是第三方机构最初开始去做的,起步比较早资料比较完善,但是会收费的,Pyside 主要是Python 他们自己去维护的,相当于Python的亲儿子PyQT相当于干儿子,所以目前大家都比较看好Pyside,我这里是使用的Pyside2 其实目前Pyside 和PyQT大部分是兼容的,你只需要将PyQT的名字改为Pyside就可以了。
一、Python知识1、初识Python??对于Python而言,和C++一样的都是高级语言,都是面向对象的语言。
2、Python输入输出控制??Python中使用input和print实现输入输出控制,输入input默认类型是str类型的,需要其他类型需要做数据类型的转换。
2.1、Python的输入input??输入input() 注意 输入默认是 str类型的,需要其他类型需要类型转换
name = input("请输入你的名字>>")
print(name)
password = input("请输入你的密码>>")
print(password)
print(type(password))   # 'str'>
2.2、Python的输出控制print??Python的输出控制使用的是print来实现输出显示的,和C一样的可以使用控制输出符实现对输出格式的控制。Python的输出print的输出控制有许多种类别。直接使用占位符实现输出、使用xxx.format形式、使用f"{}"的形式。速度对比f'{}'>str.format()(推荐使用)>%(占位符),值得注意的是下面使用到字符串的显示,字符串通常可以 ”(字符串)“、'(字符串)'、'''(字符串)'''三种形式显示字符串,最后这种可以显示多行换行形式的字符串。2.2.1、使用占位符输出% 占位符有%s %d %f
name = input("name:")
age = input("age:")
job = input("Job:")
hobbies = input("hobbies:")
info = '''
---------------info of------------
Name    :%s             #代表name
Age     :%s             #代表Age
Job     :%s             #代表Job
Hobbies :%s             #代表Hobbies
'''%(name,age,job,hobbies)
print(info)
msg = "my name is %s"%('shawn')
print(msg)  # my name is shawn
msg = "my name is %s,my age is %s"%('shawn',22)
print(msg)  # my name is shawn,my age is 22
2.2.2、使用xxx.format形式
msg = "my name is {}".format('shawn')
print(msg)  # my name is shawn
msg = "my name is {} my age is {}".format('shawn',18)
print(msg)  # my name is shawn my age is 18
msg = "my name is {0} my age is {1} {1}".format('shawn',18)
print(msg)  # my name is shawn my age is 18 18
2.2.3、f"{}"的形式
name = 'shawn'
age = 18
print(f"my name is {name} my age is {age}") # my name is shawn my age is 18
3、Python的数据结构3.1、数字??在Python中例如(2、4、6)归类为int整形数据,带有小数的数字(3.14、9.9)称之为float(浮点型)。在Python3中使用 ”/“ 返回的永远是一个浮点型,想要除法最后获得整形类型就使用”//“,即可实现,但是最后的整形数据是直接截掉后面的小数,不是四舍五入之后的数据;想要获取两数之后的余数使用”%“即可实现。实现指数运算直接使用”**“来实现。此外python还支持复数来定义虚实部计算。
print(7 / 3)
print(7 // 3)
print(7 % 3)
print(7 ** 3)
输出结果:
2.3333333333333335
2
1
343
3.2、字符串??在Python中可以使用”''“(单引号)或“""”(双引号)括起来代表字符串,也可以使用”\“来对特殊的字符转意,如果想要表示多行字符串,就可以使用” """...""" “ 三个双引号或者” '''...''' “ 三个单引号把字符串扩起来,每行结尾都会被自动加上一个换行符,如果不想输出换行符可以在每行的最后加入 ”\“ 来避免输出行换。
print("""
How are you?\
I`m fine.
""")
print("""
How are you?
I`m fine.
""")
3.3、数据结构之通用序列操作??Python中有六种内置序列,其中三种基本序列类型比较常见:列表、元组、字符串,大部分序列都可以进行通用操作,包括索引、切片、相同序列相加、乘法、成员资格、长度、最大值、最小值。
3.3.1、索引??序列的每一个元素都会为其分配一个数字,代表序列中的索引的位置,Python中的索引和C语言的素组一样的从下标0开始的。不仅可以正数,还可以倒数,负数时候索引的值从右往左的顺序。
x1 = [1, 2, 3, 4]
print("列表", x1[0])
x2 = (1, 2, 3, 4)
print("元组", x2[0])
print("元组", x2[-1])
输出结果:
列表值 1
元组值 1
元组值 4
3.3.2、切片??利用切片我们可以连续的获取或者输出一段序列的内容,在Python中所有的序列类型都可以支持切片操作。切片主要有三个参数组成  切片索引开始值 :切片索引结束值 :切片步距 固定格式就是这样的但是我们并不一定看到的都是这样的格式,可以进行一些简写格式的输出。
x1 = [1, 2, 3, 4, 5, 6, 7, 8]
print(x1[:])        # 全切片
print(x1[0:7:2])    # 指定开始结束位置以及步距的切片
print(x1[3:])       # 指定开始默认一直到结束 步距默认为1
print(x1[:3])       # 指定结束位置默认索引从0下标开始算起 步距默认为1
print(x1[3:5])      # 指定开始结束位置 步距默认为1 位置为左开右闭 即第五位不输出,索引从0下标开始算起 索引数字3的时候开始切片 数字5的时候结束,但不包括索引下标5所对应的值
print(x1[-6:5])     # 切片值支持负数索引
输出结果:
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 3, 5, 7]
[4, 5, 6, 7, 8]
[1, 2, 3]
[4, 5]
[3, 4, 5]
3.3.3、序列相加??序列相加直接可以使用 ”+“进行连接操作。
x1 = [1, 2, 3, 4, 5, 6, 7, 8]
x2 = [9, 10, 11, 12, 13, 14]
x3 = x1 + x2
print(x3)
输出结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
3.3.3、序列重复??序列重复直接使用 “*” 星号叫做乘号
x1 = [1, 2, 3, 4, 5, 6, 7, 8]
x3 = x1 * 2
print(x3)
输出结果:
[1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8]
3.3.4、成员资格??成员资格使用 “in” 来判断一个元素是否包含在序列中,如果包含则返回True,不包含则返回False ,但是在进行包含判断的只有元素的类型和值完全一致的时候次才可以实现包含,例如不能使用字符5和数字5来处理包含关系。
x1 = [1, 2, 3, 4, 5, 6, 7, 8]
print("5是否包含在x1  列表中", 5 in x1)
print("10是否包含在x1 列表中", 10 in x1)
输出结果:
5是否包含在x1  列表中 True
10是否包含在x1 列表中 False
3.3.4、长度、最值、求和x1 = [1, 2, 3, 4, 5, 6, 7, 8]
print("x1列表长度值", len(x1))
print("x1列表最大值", max(x1))
print("x1列表最小值", min(x1))
print("x1列表总和值", sum(x1))
输出结果:
x1列表长度值 8
x1列表最大值 8
x1列表最小值 1
x1列表总和值 36
3.4、列表??列表在Python中的功能是非常强大的,也是Python中重要的数据结构。列表也可以通过索引来获取和设置数,我们还可以增删和查找列表中的数据。列表不单纯是一类数据还可以是多种类型的数据。
3.4.1、新增元素??Python中的新增数据可以使用append来添加,但是只在列表中新增一个元素,想要新增多个元素的话还的使用extend,append无论后面是一个列表都只能按照一个元素新增上去,extend则是打散之后加载在原来的列表后面。使用append和extend都是只能在列表的最后面添加元素,我们可以使用insert在指定的序列添加指定的数据。insert和append一样的一此只能插入一个数据,insert插入的序列下标还是从0开始计算的。
x1 = [1, 2, 3, 4, 5, 6, 7, 8]
print("x1修改前的数据", x1)
x1[3] = "Hello"
print("x1修改后的数据", x1)
x1.append("Python")
print("x1 append 新增后的数据", x1)   # append只能新增一个元素
x1.append([168, 99])
print("x1 append 新增后的数据", x1)   # append只能新增一个元素
x1.extend([99, 168])
print("x1 extend 新增后的数据", x1)   # append只能新增一个元素
x1.insert(1, 66)
print("x1 insert 新增后的数据", x1)   # append只能新增一个元素
输出结果:
x1修改前的数据 [1, 2, 3, 4, 5, 6, 7, 8]
x1修改后的数据 [1, 2, 3, 'Hello', 5, 6, 7, 8]
x1 append 新增后的数据 [1, 2, 3, 'Hello', 5, 6, 7, 8, 'Python']
x1 append 新增后的数据 [1, 2, 3, 'Hello', 5, 6, 7, 8, 'Python', [168, 99]]
x1 extend 新增后的数据 [1, 2, 3, 'Hello', 5, 6, 7, 8, 'Python', [168, 99], 99, 168]
x1 insert 新增后的数据 [1, 66, 2, 3, 'Hello', 5, 6, 7, 8, 'Python', [168, 99], 99, 168]
3.4.2、删除元素??对于列表能新增当然也可以删除元素,删除元素可以使用pop和remove来实现,pop是默认删除最后一个元素,并且返回删除的元素值,此外pop也可以通过参数指定删除哪一个数值,remove的话是可以根据值索引删除的。remove删除值之后不会返回删除的值,直接返回一个None,remove删除时候索引找不到该值的时候就会报错。另外也可以使用del来实现列表元素的删除。
x1 = [1, "Hello", 3, 4, 5, 6, 7, 8]
print("使用pop删除之后的返回值", x1.pop())
print("删除之后的值", x1)
print("使用pop删除之后的返回值", x1.pop(0))
print("删除之后的值", x1)
print("使用remove删除之后的返回值", x1.remove("Hello"))
print("删除之后的值", x1)
del x1[4]
print("del删除之后的值", x1)
输出结果:
使用pop删除之后的返回值 8
删除之后的值 [1, 'Hello', 3, 4, 5, 6, 7]
使用pop删除之后的返回值 1
删除之后的值 ['Hello', 3, 4, 5, 6, 7]
使用remove删除之后的返回值 None
删除之后的值 [3, 4, 5, 6, 7]
del删除之后的值 [3, 4, 5, 6]
3.4.3、查找元素??Python中使用index方法查找元素在列表中的索引位置。当查找元素不存在的时候会报错。除此之外列表还有些其他的方法可以操作,例如反转队列reverse、计算元素在列表中出现的次数count、排序sort。注意排序sort的时候需要列表的数据类型一致,不然会报错。
x1 = [1, 2, 3, 4, 5, 6, 7, 8]
print("index 查找元素位置", x1.index(2))
x1.reverse()
print("reverse 反转列表数据", x1)
print("count 计数列表数据值出现次数", x1.count(6))
x1.sort()
print("sort 排序后的列表", x1)
输出结果:
index 查找元素位置 1
reverse 反转列表数据 [8, 7, 6, 5, 4, 3, 2, 1]
count 计数列表数据值出现次数 1
sort 排序后的列表 [1, 2, 3, 4, 5, 6, 7, 8]
3.5、元组??元组与列表十分相似,但是元组与列表最大的区别是列表可以修改、读取、删除,而元组创建之后则不能修改和不能删除单个元素。元组还是有count、和index的可以索引和对元素计数的。??元组的定义只需要使用() 括号扩起来就行了,并且使用 ”,“ 来隔开元素。如果只有一个元素的时候单单只有一个 ”()“是不够的,还需要加上一个 ”,“才能定义一个元组。
x1 = (1, 2, 3, 6, 9)
print("count 计数元组数据值出现次数", x1.count(6))
print("count 计数元组数据元素的索引值", x1.index(6))
x2 = ("Hello")
x3 = ("Hello",)
print("x2数据类型", type(x2), "x3数据类型", type(x3))
输出结果:
count 计数元组数据值出现次数 1
count 计数元组数据元素的索引值 3
x2数据类型 class 'str'> x3数据类型 class 'tuple'>
3.6、字典??字典的类型就和json字符串类似的样子,你可以像查字典一样的使用字典。字典类中的元素由键key和值value构成元素和元素之间使用 ”,“分隔整个字典使用 ”{}“ 花括号来包围。字典中的键必须是唯一的不能重复,如果是空字典的话直接使用 {} 表示。??字典可以通过key值去获取和索引字典元素中的值,此外还可以对字典的数据进行增删操作等等。
  • del:来实现对字典的删除
  • clear:对字典进行清空处理
  • copy:可以实现对字典的复制
  • fromkeys:可以实现创建一个字典
  • get:放回键对应的值
  • keys:返回一个列表,里面包含所有的键,通常判断一个键是否包含于字典中我们只需要得到这个列表在使用 ”in“ 操作即可实现
  • value:返回一个列表,包含字典的所有值
  • items:方法放回一个列表,包含所有的键和值列表,由于字典不能直接用for循环,通常我们可以使用iteams方法来遍历整个字典language = {
        "chinese": "汉语",
        "english": "英语",
        "other": "其他语言"
    }
    print("原来值", language)
    print("索引值", language["chinese"])
    language["other"] = "鸟语"
    print("设定值", language["other"])
    language["alien"] = "火星语"
    print("新增值", language["alien"])
    del language["other"]
    print("删除后值", language)
    language.clear()
    print("clear 后的值", language)

    language_key = ("chinese", "english", "other")
    language = dict.fromkeys(language_key)
    language1 = dict.fromkeys(language_key, "汉语")
    language2 = language1.copy()
    print("字典language", language, "
    字典language1", language1, "
    字典language2", language2)
    print("获取字典language1的值", language1.get("chinese"))
    print("chinese 是否存在字典中?", "chinese" in language1.keys())
    print("language1 中所有的值", language1.values())
    print("使用items遍历字典")
    for k, v in language1.items():
        print("key:", k, "value:", v)
    输出结果:
    原来值 {'chinese': '汉语', 'english': '英语', 'other': '其他语言'}
    索引值 汉语
    设定值 鸟语
    新增值 火星语
    删除后值 {'chinese': '汉语', 'english': '英语', 'alien': '火星语'}
    clear 后的值 {}
    字典language {'chinese': None, 'english': None, 'other': None}
    字典language1 {'chinese': '汉语', 'english': '汉语', 'other': '汉语'}
    字典language2 {'chinese': '汉语', 'english': '汉语', 'other': '汉语'}
    获取字典language1的值 汉语
    chinese 是否存在字典中? True
    language1 中所有的值 dict_values(['汉语', '汉语', '汉语'])
    使用items遍历字典
    key: chinese value: 汉语
    key: english value: 汉语
    key: other value: 汉语
    3.7、集合??集合的数与列表数据非常类似,集合唯一的区别是不会包含重复的数据。如果是空集合一定要使用set()来定义,如果包含元素则可以使用 “{}” 来定义,在集合中可以使用add来添加对应的元素,也可以使用remove来移除集合中的数,但是不能用来移除不存在的数,不然Python会报错。
    empty = set()  # 注意空集合不能使用{}定义
    print("空集合", empty)
    number = {1, 5, 1, 10}
    print("数字集合", number)
    mix = {1, "hello", 3.1415926}
    print("混合集合", type(mix), mix)
    mix.add("66")
    print("添加后的元素", mix)
    mix.remove("hello")
    print("移除后的元素", mix)
    输出结果:
    空集合 set()
    数字集合 {1, 10, 5}
    混合集合 class 'set'> {1, 3.1415926, 'hello'}
    添加后的元素 {1, '66', 3.1415926, 'hello'}
    移除后的元素 {1, '66', 3.1415926}
    3.8、推导公式??Python中支持三种推导公式,风别对应列表、字典、集合;推导公式的用法用中括号扩起来中间用for语句,后面跟着用if语句作为判断,满足条件的传到for语句前面用作构建列表。
    a1 = [x for x in range(5)]
    print("列表a1", a1)
    odd = [x for x in range(5) if x % 2 != 0]
    print("列表odd", odd)
    d1 = {n: n**2 for n in range(5)}
    print("字典d1", d1)
    d2 = {v: k for k, v in d1.items()}
    print("字典d2", d2)
    s1 = {i ** 2 for i in [-1, -2, 1, 3, -3]}
    print("集合d1", s1)
    输出结果:
    列表a1 [0, 1, 2, 3, 4]
    列表odd [1, 3]
    字典d1 {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
    字典d2 {0: 0, 1: 1, 4: 2, 9: 3, 16: 4}
    集合d1 {1, 4, 9}
    4、Python 的流程控制4.1 if判断4.1.1、单独if 语句输出格式:
    if 表达式:
    语句1
    语句2
    ......
    ??python是严格的遵守索引的,语句或者一段表达式都是按照缩进来实现区分的,因此语句1、语句2前面的空格是严格遵守一个tab键,四个空格的。i放后面的表达式不仅仅支持布尔类型的,还可以是数字,只有数字0才会判断为 False,如果测试的为字符串只有空字符串的条件结果才会为False,空列表、空元组、空字典的条件才会是False。
    list1 = []
    set1 = set()
    str1 = ""
    number1 = 0

    if list1:
        print("输出False")
    if set1:
        print("输出False")
    if str1:
        print("输出False")
    if number1:
        print("输出False")
       
    4.1.2、else语句??当前面的if语句执行不满足条件的时候才会执行后面的else语句。
    list1 = []
    if list1:
        print("list1 不是一个空列表")
    else:
        print("list1 是一个空列表")
    输出结果:
    list1 是一个空列表
    4.1.3、elif语句??当if的判断有超过两种情况的时候这个时候elif就可以排上用场了。
    number = 18
    if number 16:
        print("小于16")
    elif number == 16:
        print("等于16")
    else:
        print("大于16")
       
    输出结果:
    大于16
    4.2 循环4.2.1、while循环输出格式:
    while 表达式:
    语句1
    语句2
    ......
    ??while循环语句是python中最简单的循环语句。while和if都是一样的条件测试,只有满足条件才会执行。
    number = 6
    while number 9:
        print("number:", number)
        number += 1
       
    输出结果:
    number: 6
    number: 7
    number: 8
    number: 9
    4.2.2、for循环输出格式:
    for 变量 in 序列:
    语句1
    语句2
    ......
    ??for循环比while循环的用法更加丰富,其中序列可以是列表元组等其他可迭代的对象,变量逐一遍历 in后面序列中的每一个元素。
    for x in range(1, 10):
        print("变量值", x)
       
    输出结果:
    变量值 1
    变量值 2
    变量值 3
    变量值 4
    变量值 5
    变量值 6
    变量值 7
    变量值 8
    变量值 9
    4.2.3、break、continue、和pass值?? 对于循环for 和 while而言,没有任何中断打断则会直至循环条件不满足和遍历整合序列之后才会结束,我们可以使用break和continue实现对特定情形下实现退出循环;break的作用是立即退出循环体,直接结束循环,continue并不会立即退出循环,而是跳过当前的循环体执行之后的循环。在Python中 pass语句就是空语句,其中的作用就是保持程序语句的完整性。
    for x in range(1, 5):
        if x == 2:
            break
        print("变量值", x)
    print("continue 输出")
    for x in range(1, 5):
        if x == 2:
            continue
        print("变量值", x)

    x = 35
    if x == 35:
        pass
        # 注释 TODO 没有 pass就会报错
    else:
        print("输出value")
            
    输出结果:
    变量值 1
    continue 输出
    变量值 1
    变量值 3
    变量值 4
    4.2.4、循环中的else??在Python中 while和for都可以结合else一起使用,当while测试为False的时候就会执行else,但是值得注意的是中途中遇到break就不会在执行else,同样for也是一样的情况。
    number = 1
    while number 5:
        number += 1
        print("变量值", number)
    else:
        print("执行else之后的变量值", number)
    print("continue 输出")
    for x in range(1, 5):
        if x == 2:
            break
        print("变量值", x)
    else:
        print("执行else之后的变量值", x)
    输出结果:
    变量值 2
    变量值 3
    变量值 4
    变量值 5
    执行else之后的变量值 5
    continue 输出
    变量值 1
    4.3、运算符4.3.1、算术运算符操作符描述示例+加法:运算两侧值相加a+b-减法:运算两侧值相加a-b*乘法:左操作数乘上有操作数a*b/除法:左操作数除于有操作数a/b%取模:返回左操作数除于右操作数的余数a%b**幂:返回幂之后的数a**b//取整除:放回商的部分a//b4.3.2、比较运算符操作符描述示例==等于:比较对象是否相等a == b!=不等于:比较对象是不否相等a != b>大于:返回a 是否大于ba > b=大于等于:返回a 是否大于等于ba >= b4.3.3、赋值运算符操作符描述示例展开形式=右边值赋给左边a = 100a = 100+=右边值加到左边a += 100a = a + 100-=右边值减到左边a -= 100a = a - 100*=左边值除于右边值a *= 100a = a * 100/=左边值对右边进行取模运算a /= 100a = a / 100**=左边值对右边进行幂运算a **= 100a = a ** 100//=左边值整除右边a //= 100a = a // 1004.3.4、位运算符操作符描述示例&按位与:对应a、b都为1则为1 否则为0a & b|按位或:对应a、b都为0则为0 否则为1a | b^按位异或:对应a、b都相同则0 否则为1a ^ b~按位取反:运算符操作数里的每一位 0变1,1变0~ a>按位右移运算符:左移操作数按位右移右操作数指定的位数a >> b4.3.4、逻辑运算符操作符描述示例and逻辑与:两个都为真 则为真,否则为假a and bor逻辑或:两个中一个为真即为真a or bnot逻辑非:反转操作数的逻辑,真变为假,假变为真not a5、函数??Python中与C、C++、以及java中的函数还是有些区别的。一般C和C++函数的开始都是返回类型,但是Python并不是这样的。定义一个函数只要以 def 开头即可。其中函数名和c、c++一样的,有效函数名以字母或下划线开头,后面可以跟字母、数字、下划线。输出格式:
    def function_name(arg1, arg2):
        function body
        return value
    ......
    5.1、函数参数??在创建函数的时候,可以设置参数也可以不用设置参数,在python函数参数有以下几种:
    必须参数: 调用函数时必须要传入参数,并且传入参数的顺序也要一致。关键字参数: 使用关键字可以不按函数定义时的参数顺序传入参数。默认参数: 在函数定义时我们可以给函数添加默认值,在调用时没有传入参数就是用默认参数。可变参数: 在定义函数时候不能确定使用时候的参数个数和内容时候就可以使用可变参数。
    # 必须参数
    def add(a, b):
        print("a + b = ", a + b)

    # 关键字型参数
    def person(name, age):
        print("姓名:", name, "
    年龄:", age)

    # 默认参数
    def default_args(name="wsp", age="24"):
        print("名字:", name, "年龄:", age)

    # 可变参数1
    def function_args_one(*args):
        print(args)

    # 可变参数2
    def function_args_two(**kwargs):
        print(kwargs)

    # 组合可变参数3
    def function_args_three(*args, **kwargs):
        print(args, kwargs)

    add(99, 168)
    person(age=18, name="小花")
    default_args()
    function_args_one("小花", 18, "上海")
    function_args_two(name="小花", age=18, location="上海")
    function_args_three(1, 2, 3, 4, 5, 6, name="小花", age=18)
    输出结果:
    a + b =  267
    姓名: 小花
    年龄: 18
    名字:wsp 年龄: 24
    ('小花', 18, '上海')
    {'name': '小花', 'age': 18, 'location': '上海'}
    (1, 2, 3, 4, 5, 6) {'name': '小花', 'age': 18}
    ??关键字型参数参数可以不按照函数定义时候的顺序赋值,可变参数 * args参数获取到的是一个元组,这也是它能作为卡变参数的原因。** kwargs 参数获取到是一个字典,再调用函数的时候就要使用关键字的方式来传递参数。
    5.2、函数返回值??如果我们想要返回函中的局部变量,使用return作为函数的返回值。不需要像c或者c++在函数前面声明返回数据类型。函数中没有return或者return后面没有跟上任何参数,则返回数据为None。python的返回值还有更高的特性就是返回值不止一个可以有多个返回值。
    # 单独一个值的返回类型
    def add(a, b):
        print("a + b = ", a + b)
        return a + b

    # 多个值的返回类型
    def function_args():
        str1 = "args1"
        str2 = "args2"
        str3 = "args3"
        return str1, str2, str3

    print(add(66, 99))
    r1, r2, r3 = function_args()
    print("函数返回值", r1, r2, r3)

    输出结果:
    a + b =  165
    165
    函数返回值 args1 args2 args3
    5.3、变量的作用域??在C语言中我们都经常会使用到的变量,分为局部变量和全局变量,在python中也是一样的,分为局部变量和全局变量。?? 在函数内赋值的变量,一般不做特殊声明的变量都是局部变量;在函数外赋值的变量就是全局变量。如果想要对函数外的变量进行修改的话,这个时候我们可以使用global关键字。
    # 全局变量
    str1 = "外部参数1"
    str2 = "外部参数2"

    def function_one():
        global str2
        str1 = "内部参数1"
        print(str1)
        print(str2)
        str2 = "函数内修改外部参数2"
        print(str2)

    function_one()
    print(str1)
    输出结果:
    内部参数1
    外部参数2
    函数内修改外部参数2
    外部参数1
    5.4、Lambda表达式??表达式也称为匿名函数,类似于c语言中的三目运算符。具体形式以lambda开头,之后内容以":"分为两部分,左边是函数的参数,右边是要返回的值。lambda表达式中就不需要return作为返回值了。
    f = lambda x, y: x + y
    z = f(66, 99)
    print(z)
    输出结果:
    165
    6、面向对象6.1、介绍??python和C++都是面向对象的,最基本的就是类、继承和封装。接下来简单的介绍一下面向对象的基本特征。
    专有名词解释类用来描述具有相同的属性和方法的对象的集合。类变量类变量在整个实例化的对象中是公用的,类变量定义在类中并在函数体之外,通常不作为实例变量使用。数据成员类变量或者实例变量,用于处理类机器实例化对象的相关数据。方法重写如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫做方法的覆盖,也称为方法的重写。实例变量定义在方法中的变量,只作用于当前实例的类。继承指一个派生的类继承基类的字段和方法。继承也允许把一个派生类的对象作为一个基类对待。实例化创建一个类的实例,一个类的具体对象。方法类中定义的函数。对象通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。??python对象介绍示例。
    # Animal 类
    class Animal:
        # 类属性 类属性是类体中所有方法外的变量 称之为类属性或类变量
        Animal = 'animal'
        # 构造函数 创建类的时候就会调用
        def __init__(self):
            # 实例属性 类体中方法内并且命名格式为 self.变量名 = 变量值,称之为实例变量
            self.get_name = "animal"    # 实例变量
            print("实例化类时候调用")
        def name(self):
            print("Animal")
        # 类方法 必须要有self
        def set_name(self, name):
            self.get_name = name        # 在类方法中直接可以引用实例变量
            # 局部变量 类体中方法内 以 变量名 = 变量值的方式, 称之为局部变量
            set_name = self.get_name    # set_name 局部变量
            print("设置后的数据", set_name, self.get_name)
        # 析构函数
        def __del__(self):
            print("销毁类的时候调用")

    # Cat 继承Animal
    class Cat(Animal):
        # 多态性 在新类中可以重新定义一个方法和父类中一样的方法
        def name(self):
            print("Cat Animal")
        # 静态方法 没有self
        @staticmethod
        def Cat_name():
            print("my name is cat")

    Cat.Cat_name()          # 直接调用静态方法不用实例化化成类都可以调用
    cat = Cat()             # 实例化 cat
    cat.name()              # 调用方法 这个时候由于多态性调用的是Cat下面的方法
    cat.set_name("小猫咪")   # 调用父类中的方法,实现继承方法
    输出结果:
    my name is cat
    实例化类时候调用
    Cat Animal
    设置后的数据 小猫咪 小猫咪
    销毁类的时候调用
    6.2、定义语法输出格式:
    class [类名]:
        [语法块]
    ......
    eg:
    class new_class:
        pass

    6.3、类的使用??在使用类之前需要实例化类,类实例化之后成为常见的对象,创建对象和创建变量类似,需要先声明对象是哪个类,同时指明变量名称。
    class new_class:
        pass

    NEW_CLASS = new_class()
    print(NEW_CLASS)
    输出结果:
    0x000001BEE34BB190>
    6.4、类的构造方法??很多类都可能需要有特定的初始化状态,所以一个类可以定义一个特殊的方法,叫做够构造函数,在python中构造函数就是类的__init__方法,这个和c++的构造的命名有些不同。注意构造函数中的第一个参数是 self,不能遗漏,构造方法返回值必须None
    class new_class:
        def __init__(self):
            print("我是类中的构造方法")
        pass

    NEW_CLASS = new_class()
    输出结果:
    我是类中的构造方法
    6.5、类的属性??在构造方法中我们可以初始化一些属性,注意属性(或者叫做成员变量、类变量)必须加上“self” 加上点的方式赋值,不能直接定义变量,直接定义变量的周期会函数内,函数执行完之后就会销毁。其实函数中的 __init__的第一个参数self指的是实例本身,在C++中对应的就是this指针。
    class new_class:
        def __init__(self, name):
            self.name = name
            self.age = 18
            location = "上海"  # 直接定义变量 函数执行后就会销毁

    NEW_CLASS = new_class("小花")
    print(NEW_CLASS.name)
    print(NEW_CLASS.age)        # 调用类中属性
    print(NEW_CLASS.location)   # 执行会报错
    输出结果:
    Traceback (most recent call last):
      File "xxx\xx.py", line 11, in
        print(NEW_CLASS.location)   # 执行会报错
    AttributeError: 'new_class' object has no attribute 'location'
    小花
    18
    6.5、类的方法??在类中定义的函数我们称为方法,类中的方法和函数定义基本相同,除了方法必须定义在类里并且第一个参数必须是self(参数名不强制要求为self但是一般使用名字self以其它参数作为区分)外,其它和函数定义没有区别。
    class new_class:
        def __init__(self, name):
            self.name = name
            self.age = 18
        def class_function(self):
            print("我是类中的方法")

    NEW_CLASS = new_class("小花")
    NEW_CLASS.class_function()
    输出结果:
    我是类中的方法
    6.5、私有属性??在c++中我们对成员变量的声明有 public、private、protected 在引用类的时候对类中成员变量的访问会受到限制,python中私有属性中只要在定义属性的时候使用两条下划线作为开头,解释器就会认为这个属性是私有属性,外部不能谁便访问这个属性。我们虽然可以给私有属性赋值,但是不能直接使用类中的私有属性。
    class new_class:
        def __init__(self, name):
            self.__name = name
            self.age = 18

    NEW_CLASS = new_class("小花")
    # 调用其中的私有属性就会报错
    print(NEW_CLASS.__name)
    6.5、私有方法??私有方法和私有属性一样的只可以在类不被操作和调用。
    class new_class:
        def __method(self, name):
            self.__name = name
            self.age = 18

    NEW_CLASS = new_class("小花")
    # 调用其中的私有属性就会报错
    NEW_CLASS.__method()
    6.6、继承和多态??面向对象编程具有三大特性,封装性、继承性、多态性。
    6.6.1、继承??继承指的是保留原有的基础上在拓展新的属性和方法。原来的类称为父类,后来的类称为子类。在Python中支持多重继承,像java是不支持多重继承的,python是支持多重继承的。输出格式:
    class new_class(Baseclass1, Baseclass2):
        语法块
    ......
    ??要定义从那个父类继承,只需要在定义子类的名字后面的括号类填入父类的名字,多重继承的时候只需要使用“,”来隔开就行。继承的时候需要注意两点:
  • 在继承中如果子类定义了构造函数,则父类的构造方法__init__不会被自动调用,需要在子类的构造方法中专门调用。
  • 子类不能继承父类中的私有方法,也不能调用父类的私有方法。
    class class_one:
        def __init__(self, name):
            self.name = name
        def class_one_function_name(self):
            print("class_one_function_name input name", self.name)

    class class_two:
        def __init__(self, name):
            self.name = name
        def class_two_function_name(self):
            print("class_two_function_name input name", self.name)
        def __private_class(self):
            print('class_two 私有类', self.name)

    # 单继承
    class new_class_one(class_one):
        pass

    # 多继承
    class new_class_two(class_one, class_two):
        pass

    # 继承中子类定义构造函数
    class new_class_three(class_one):
        def __init__(self):
            super(new_class_three, self).__init__("小花")

    # 实例化对象
    print("NEW_class_one")
    NEW_class_one = new_class_one("小花")
    NEW_class_one.class_one_function_name()
    print("NEW_class_two")
    NEW_class_two = new_class_two("小花")
    # 新类多重继承
    NEW_class_two.class_one_function_name()
    NEW_class_two.class_two_function_name()
    # 不能直接调用父类中的私有方法 不然会报错
    # NEW_class_two.__private_class()
    print("NEW_class_three")
    NEW_class_three = new_class_three()
    NEW_class_three.class_one_function_name()

    输出结果:
    NEW_class_one
    class_one_function_name input name 小花
    NEW_class_two
    class_one_function_name input name 小花
    class_two_function_name input name 小花
    NEW_class_three
    class_one_function_name input name 小花
    6.6.2、多态??继承可以帮助我们重复使用代码,但是有时候子类的行为不一定和父类一样。下面就是我们在调用同一个方法时候我们想要输出不同的结果的时候却是输出相同的结果。
    class Animal:
        def name(self):
            print("Animal")

    class Cat(Animal):
        pass

    class Dog(Animal):
        pass

    Animal_Cat = Cat()
    Animal_Cat.name()
    Animal_Dog = Dog()
    Animal_Dog.name()
    输出结果:
    Animal
    Animal
    ??在python中的多态和c++中的虚函数一样表达意思,python中子类的方法会覆盖掉的父类中相同名字的方法。
    class Animal:
        def name(self):
            print("Animal")

    class Cat(Animal):
        def name(self):
            print("Cat")
        pass

    class Dog(Animal):
        def name(self):
            print("Dog")
        pass

    Animal_Cat = Cat()
    Animal_Cat.name()
    Animal_Dog = Dog()
    Animal_Dog.name()
    输出结果:
    Cat
    Dog
    6.6.3、类知识拓展类变量和实例变量??类变量不需要实例化直接使用,相当于绑定在类上,不是实例化上。但是类变量在实例化之后也是可以被调用的。注意实例不能修改类变量。类变量的形式:
  • 可变变量作为类变量:对于列表、字典、自定义类这些可变变量,如果将其作为类变量,则是传引用。即所有对象的类变量公用一个内存地址。
  • 不可变变量作为类变量:对于INT,STRING这种不可变变量,如果将其作为类变量,则是传值。即所有对象的类变量有各自的内存地址。??不管是可变变量还是不可变变量,只要是放在构造函数中,则都是传值。即各个对象拥有自己的对象属性。
    class Animal:
        name = "Animal"     # 类变量
        age_number = [1, 2, 3]

    print(Animal.name, Animal.age_number)               # 没有实例化对象就可以直接调用类变量
    animal = Animal()
    print("实例化后输出类变量", animal.name)               # 实例化后的对象继承了类变量
    animal.name = "animal"
    animal.age_number[0] = 6
    print("在实例化对象中修改类变量后类变量的结果", Animal.name, Animal.age_number)   # 可以看出修改实例化后的对象中的类变量不会影响类中类变量
    print("实例化后对象中的属性结果", animal.name, animal.age_number)               # 可以看出修改实例化后的对象中的类变量不会影响类中类变量
    Animal.name = "animal 修改"
    Animal.age_number[0] = 9
    print("直接修改类变量后看看实例化后的对象中的属性结果", animal.name, Animal.age_number)   # 直接修改类变量之后实例化中的属性没有被修改
    print("直接修改类变量后类成员是结果", Animal.name, Animal.age_number)           # 直接修改类变量之后实例化中的属性没有被修改

    输出结果:
    Animal [1, 2, 3]
    实例化后输出类变量 Animal
    在实例化对象中修改类变量后类变量的结果 Animal [6, 2, 3]
    实例化后对象中的属性结果 animal [6, 2, 3]
    直接修改类变量后看看实例化后的对象中的属性结果 animal [9, 2, 3]
    直接修改类变量后类成员是结果 animal 修改 [9, 2, 3]
    静态方法与类方法??静态方法的语法是在定义函数的上面一行(不能含有空格行)添加一句@staticmethod,这一句是装饰器,在后面信号与槽中也会涉及到装饰器的用法,静态方法中不需要有第一个参数 “self“,因此静态方法不能调用其类的成员方法和成员变量,静态方法不需要实例化之后才可以使用,而是和类变量一样的方法就可以直接使用,和其他一般函数使用没有任何区别。
    class Animal:
        @staticmethod
        def name():
            print("Animal")

    Animal.name()
    输出结果:
    Animal
    7、模块7.1、模块介绍??模块就是一个包含了python定义和声明的”.py“文件。例如我们定义”main.py“的文件。
    7.2、__name__变量??模块的模块名可以通过全局变量 ”__name__“ 获得。
    class Animal:
        @staticmethod
        def name():
            print("Animal")

    if __name__ == "__main__":
        Animal.name()
       
    输出结果:
    Animal
    7.2、dir函数??dir函数可以列出对象的模块标识符,标识符有函数、类和变量。
    import PySide2
    print(dir(PySide2))
    输出结果:
    ['__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '__version_info__', '_additional_dll_directories', '_setupQtDirectories', 'dedent', 'os', 'print_function', 'support', 'sys']
    7.3、使用模块??使用模块一种直接的方法直接 ”import“ 要导入的文件,还有另外一种导入模块的方法就是”from ... import ...“,它可以然我们导入模块中指定的一部分到我们当前命名空间。
    import PySide2
    from PySide2 import QtGui
    print(dir(PySide2))
    7.4、错误和异常7.4.1、错误??在python中最容易的错误就是python中的语法错误。
    print aaa
    7.4.2、异常??在前面的学习python中时不时偶尔弄错就会出现报错,报错在pycharm 中会提示我们错误在那个位置中,我们很快定位错误的位置,但是在运行一些逻辑或者代码的时候会发生意向不到的错误,运行时候检测到的错误称为异常,有些错错误并是致命的,但是大多数的异常都不做处理,python解析器会输出异常信息到屏幕上别且终止运行。
    print(1 / 0)
    str1 = "1"
    print(str1 + 0)
    dir1 = {}
    print(dir1["name"])
    输出结果:
    都是运行错误
    7.4.3、异常处理??异常处理是在运行中才会检测到的,但是有时候是不可预测的。有些错误不是最致命的,但是我们像需要程序继续执行到结束,python中提供了异常处理。输出格式:
    try:
        语法块
    except 异常处理:
    处理异常语法块
    ??在异常处理中我们需要关键字 try和except ,java也是一样的关键字,使用这两个关键字来捕获异常处理出现异常处理我们就会跑到异常处理处去处理对应的异常。ValueError是内建的一个异常,其中python中内建的异常处理还有许多的。其中我们 可以使用except as 来获取不同类型的错误。
    while True:
        try:
            number = int(input("输入一个数字:"))
        except ValueError:
            print("输入的不是数字")
    输出结果:
    输入一个数字:12
    输入一个数字:as
    输入的不是数字
    输入一个数字:

    try:
        print(1 / 0)
    except ValueError:   # 只接受特定错误
        print("发生遗产处理")

    try:
        # print("1" + 1)
        print(1 / 0)
    except Exception as e:   # 接受所有类型错误
        print("发生遗产处理", e)
    7.4.4、finally子句??在python中finally子句需要和try子句一起使用,finally子句在异常处理中的作用是:无论是否有异常处或者是否捕获了异常,finally最终都会执行,这个处理在以后可能会使用到的数据库和文件处理中是非常有用的。
    try:
        print(1 / 0)
    except ValueError:
        print("发生遗产处理")
    finally:
        print("到处一游")
    输出结果:
    Traceback (most recent call last):
      File "xxx\xxx.py", line 2, in
        print(1 / 0)
    ZeroDivisionError: division by zero
    到处一游
    8、多线程和进程8.1.进程基本概念??进程是计算机运行程序的实体,曾经是分时系统的基本运作单位,进程本身不是基本运行单位,而是线程的容器。
    8.2.线程基本概念??线程是操作系统进行运算调度的最小单位,它包含在进程中,是进程中的实际运行单位。一个进程是一个单一顺序的控制流,一个线程可以运行多个进程,每个线程并行执行不同的任务。
    8.3.python线程模块_thread模块??标准库中的_thread模块作为最低级别的模块存在,一般不建议使用,但是在一些简单的场合还是可以使用的,因为标准库的用法十分简单,标准库的核心其实就是start_new_thread方法,_thread.start_new_thread(function, args, kwargs=None)。??启动一个新线程并返回其标识符,线程使用参数列表args(必须是元组)执行函数,可选的kwargs是指定关键字的参数的字典,当线程返回时,线程将以静默方式退出。
    import time
    import datetime
    import _thread
    data_time_format = "%H:%M:%S"

    def get_time_str():
        now = datetime.datetime.now()
        return datetime.datetime.strftime(now, data_time_format)

    def thread_function(thread_id):
        print("thread %d         start at %s" % (thread_id, get_time_str()))
        print("thread %d         sleeping", thread_id)

    def main():
        print("Main thread start at %s" % get_time_str())
        for i in range(5):
            _thread.start_new_thread(thread_function, (i, ))
            time.sleep(1)
        time.sleep(6)
        print("Main thread finish at %s" % get_time_str())

    if __name__ == "__main__":
        main()
       
    输出结果:
    Main thread start at 20:24:24
    thread 0  start at 20:24:24
    thread %d  sleeping 0
    thread 1  start at 20:24:25
    thread %d  sleeping 1
    thread 2  start at 20:24:26
    thread %d  sleeping 2
    thread 3  start at 20:24:27
    thread %d  sleeping 3
    thread 4  start at 20:24:28
    thread %d  sleeping 4
    Main thread finish at 20:24:35
    Threading.thread??在python中标准库中提供_thread这样底层线程模块,还提供了threading模块,线程不仅提供了面向对象的线程方式,还提供了各种有用的对象和方法方便我们创建和控制线程。
    import time
    import datetime
    import threading
    data_time_format = "%H:%M:%S"

    def get_time_str():
        now = datetime.datetime.now()
        return datetime.datetime.strftime(now, data_time_format)

    def thread_function(thread_id):
        print("thread %d         start at %s" % (thread_id, get_time_str()))
        print("thread %d         sleeping", thread_id)

    def main():
        print("Main thread start at %s" % get_time_str())
        threads = []
        # 创建线程
        for i in range(5):
            thread = threading.Thread(target=thread_function,args=(i,))
            threads.append(thread)
        # 启动线程
        for i in range(5):
            threads.start()
            time.sleep(1)
        # 等待线程执行完毕
        for i in range(5):
            threads.join()
        print("Main thread finish at %s" % get_time_str())

    if __name__ == "__main__":
        main()
       
    输出结果:
    Main thread start at 20:50:39
    thread 0  start at 20:50:39
    thread %d  sleeping 0
    thread 1  start at 20:50:40
    thread %d  sleeping 1
    thread 2  start at 20:50:41
    thread %d  sleeping 2
    thread 3  start at 20:50:42
    thread %d  sleeping 3
    thread 4  start at 20:50:43
    thread %d  sleeping 4
    Main thread finish at 20:50:44
    ??我们在调用threading.Thread对象的方法start,才会正真的启动线程,最后调用threading.Thread对象中的join方法来等待线程的结束,使用threading.Thread模块可以自动的帮助我们实现管理线程锁。
    二、QT知识2.1、初识QT??Qt的跨平台特性非常的强,一套代码不用修改太多,直接通用所有的平台。可运用于MCU上,QT的三驾马车,QT下的串口串口编程、QT下的网络编程、QT下操作GPIO。
    2.2、Python下怎么结合QT一起开发设计??对于前面我们使用的是QT Designer软件 ,软件中就已经集成好了我们C++ 的开发和调试环境了,并且还有一堆的demo,我们现在使用python来开发怎么实现 界面设计之后与python代码结合起来呢,这里我使用的编程软件是pycharm,它是一款python的专门编程的IDE,也是非常好用的,我们可以使用社区版本的,可以免费使用。pycharm也可安装许多的包,就我们在前面开始的时候介绍的pyside2、PyQT5都只是python下的一个包,这个包主要的作用就是将QT设计的界面中元素翻译成Python的类,相当于一个翻译官一样的;我这里使用的是Pyside2,在安装好Pyside2包之后在包中就会有一个pyside2-designer.exe的可执行文件,这个可执行文件包含QT设计师的界面设计,就没有QT界面设计师的全部C++的编译调试的全部功能,主要的功能就是界面设计,设计好之后我们就可以保存.ui的文件,然后后面就可以使用pyside2-uic.exe可执行文件将我们的界面翻译成Python类,我们只要实例化类之后就可以正常的像其他的python类一样使用。
    2.2.1、安装Pyside2 包??对于前面我们使用的QT Designer 设计我们的界面,其中该软件是直接配合C++一起使用的,在python中的包pyside2中也包含了pyside2-designer.exe、pyside2-rcc.exe、pyside2-uic.exe几个软件,我们只需要在pycharm中安装pyside2就可以了。??对于怎样安装pyside2,我这里有两种方法。方法一:

    5pzm0ctdryq6402597905.png

    5pzm0ctdryq6402597905.png

    3zepfx2d5pw6402598005.png

    3zepfx2d5pw6402598005.png

    方法二:??这里以fibs来举例,因为我已经安装好了Pyside2。我们写入import Pyside2 ,然后会出现Pyside2 底部红线,旁边有个小红灯泡,我们直接点击红灯泡然后会提示出下面提示,我们直接选择install package Pyside2 就会自动的安装。

    nsutjfg2m2b6402598105.png

    nsutjfg2m2b6402598105.png

    2.2.2、在pycharm中添加插件??我们在安装好Pyside2之后,我们怎样将 pyside2-designer.exe、pyside2-rcc.exe、pyside2-uic.exe这几个exe文件加入我们的pycharm中呢?这几个文件又在何处找到呢?在将这几个可执行文件与pycharm关联起来我们使用的是pycharm中的外部工具,后面我们就可以很快捷的利用设定好的外部工具直接将我们的QT设计好的界面以及界面所需要的资源转换成对应的python代码。一般这几个可执行文件在我们安装好pyside2包之后就可以找得到的,你可以直接在全局文件夹中搜索。我的是安装好包之后自己在我的工程文件夹下面新建一个venv的文件,然后在该文件夹中的Script中就可以看到这三个可执行文件了。

    zb4gk1o2kg36402598205.png

    zb4gk1o2kg36402598205.png

    ??那么我们怎样配置这几个可执行文件呢,下面都是一些操作步骤,首先需要在File中打开设置选项。然后找到Tools下面的External Tools。

    2.2.2.1  配置pyside2-designer外部工具??按照下面的截图我们在步骤三中填写下我们外部工具的名字name,这个是随便我们怎么填写的方便自己记忆就行了。我这里填写的是Qt Designer;接着在Program中我们可以点击右边的文件夹的图标就会打开文件夹我们只需要根据我们安装Pyside2中的pyside2-designer.exe的路径选择即可,我这里它自动安装在F:\QT\qt-uart-Python\venv\Scripts\pyside2-designer.exe路径下的,每个人的路径不一定相同,但是最后都要选中对应的可执行文件;最后的Working directory  工作目录就是需要填写$ProjectFileDir$这样就会每次运行的时候会在当前工作目录下。我们可以这个外部工具快速的打开designer软件来实现我们界面的编辑。
    Name:    Qt Designer
    Program:   F:\QT\qt-uart-Python\venv\Scripts\pyside2-designer.exe
    Working directory: $ProjectFileDir$

    ehvh0wpyn2p6402598306.png

    ehvh0wpyn2p6402598306.png

    5olcrt2fi5i6402598406.png

    5olcrt2fi5i6402598406.png

    2.2.2.2  配置pyside2-uic外部工具??和前面配置pyside2-designer一样的步骤,我们点击加号新建新的外部工具。然后填写对应的配置即可。但是我们这个和前面designer有些区别的就是我们需要设置下Arguments 参数,将文件转换成对应的参数,这里需要这样配置,每个人的配置要相同的:-o $FileNameWithoutExtension$.py $FileName$这个转换器的主要作用就是将我们的QT设计的ui文件转换成对应的Python类,在后面我们可以以类的方式来引用界面中的方法以及属性。
    Name:    Pyside2-uic
    Program:   F:\QT\qt-uart-Python\venv\Scripts\pyside2-uic.exe
    Arguments :   -o $FileNameWithoutExtension$.py $FileName$
    Working directory: $ProjectFileDir$
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表