5 控件combobox
也就是下拉框
下拉框的主要用法就是:
- 创建下拉的内容
- 选定下拉内容
由于combobox控件没有connand方法,所以在选定下拉内容时,使用虚拟事件"<<ComboboxSelected>>"。
下面是一个简单的代码:
这个代码最让我有用的是grid布局,可以让你在窗口上的控件有序排列。
from tkinter import *
from tkinter import ttk, tix, StringVar
mywin = tix.Tk()
lb_text = StringVar()
mywin.geometry("600x200")
lb1 = tix.Label(mywin, text='下拉框选项:')
c_values=['下拉选项1', '下拉选项2', '下拉选项3', '下拉选项4']
c_values.append('下拉选项5')
cb1 = ttk.Combobox(mywin)
cb1 = ttk.Combobox(mywin, values=c_values)
#cb1['value'] = ['下拉选项1', '下拉选项2', '下拉选项3', '下拉选项4']
#cb1['value'] = c_values
cb1.current(0)
lb_text.set(cb1.get())
lb2 = tix.Label(mywin, textvariable=lb_text)
#windows中控件的位置摆放
'''grid布局'''
#sticky N,S,W,E 表示 上,下,左,右
lb1.grid(row=1, column=1, sticky='NW')
cb1.grid(row=1, column=2, sticky='NW')
lb2.grid(row=1, column=3, sticky='NW')
'''pack布局'''
#lb1.pack(pady=20)
#lb1.pack(side = LEFT,ipadx = 0, pady=0 )
#cb1.pack(side = LEFT,ipadx = 10, pady=20 )
#根据选择改变lb2的内容
def myselection(self):
lb_text.set(cb1.get())
pass
cb1.bind("<<ComboboxSelected>>", myselection)
mywin.mainloop()
运行结果:
该代码一共创建了三个控件:1,左边的Lable作为内容提示;2,中间的combobox控件;3,右边Lable,选中combobox内容后的显示
6 dict(数据字典)类型
字典是另一种可变容器模型,且可存储任意类型对象。
字典的每个键值 key:value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示:
d = {key1 : value1, key2 : value2 }
注意:dict 作为 Python 的关键字和内置函数,变量名不建议命名为 dict。
键一般是唯一的,如果重复最后的一个键值对会替换前面的,值不需要唯一。
为啥要说这个类型呢?根据我目前看过的Python代码,有很多函数返回的都是dict类型。所以需要对这个类型多多学习和理解。
7 获取本机网卡信息
7.1 使用re模块对命令行解析获取
用到的内容:
- subpross.Popen()执行ipconfig命令
- 对ipconfig得到的字符串进行正则匹配拿到想要的结果
- 分两层解析:1,网卡名称;2,网卡下的具体信息
import subprocess
import re
# 执行windows命令
def exec_command(commands):
p = subprocess.Popen(commands, shell=True, stdout=subprocess.PIPE, universal_newlines=True)
p.wait()
return p.stdout.readlines()
def get_ipinfo():
res = exec_command('ipconfig')
net_card_data = list()
temp_dict = dict(flag=True)
gateway_error = False
for x in res:
#print(x)
# 匹配IP正则
pattern = re.compile(r'(.*):(.*)|(((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3})')
# 测试发现有的网关会默认在下一行,情况见说明一,所以这边检查到默认网关,发现没有匹配到,则从下一行找
if gateway_error:
temp_dict['gateway1'] = pattern.search(x).group()
gateway_error = False
#print("当前网卡 %s 获取第二行网关信息 %s" % (temp_dict['card_name'], temp_dict['gateway1']))
continue
# 如果发现新的适配器,则重置上一个网卡是否可用的状态
if "适配器" in x:
temp_dict = dict(flag=True)
temp_dict['card_name'] = x.split(" ", 1)[1][:-1]
#print("当前网卡 %s" % (temp_dict['card_name']))
continue
if "IPv4 地址" in x:
temp_dict['ip'] = pattern.search(x).group(2)
#print("当前网卡 %s 获取IP信息 %s" % (temp_dict['card_name'], temp_dict['ip']))
continue
elif "子网掩码" in x:
temp_dict['mask'] = pattern.search(x).group(2)
#print("当前网卡 %s 获取子网掩码信息 %s" % (temp_dict['card_name'], temp_dict['mask']))
continue
# 测试发现有的网关会默认在下一行,情况见说明一,所以这边做了异常处理
elif "默认网关" in x:
try:
temp_dict['gateway1'] = pattern.search(x).group(2)
#print("当前网卡 %s 获取默认网关信息 %s" % (temp_dict['card_name'], temp_dict['gateway1']))
except:
gateway_error = True
#print("当前网卡 %s 解析当前行默认网关信息错误" % (temp_dict['card_name']))
finally:
pass
#print('未找到信息2')
# 如果检查到网关,代表当前适配器信息已经获取完毕 重置网关状态与适配器信息字典
if temp_dict.get("gateway1"):
net_card_data.append(temp_dict)
#print("当前网卡 %s 当前适配器信息获取完毕 %s \n\n" % (temp_dict['card_name'], temp_dict))
temp_dict = dict(flag=True)
continue
# 发现媒体已断开则更改当前适配器状态
elif "媒体已断开" in x:
#print("当前网卡 %s 已断开 跳过\n\n" % (temp_dict['card_name']))
temp_dict['flag'] = False
continue
# 判断媒体状态正常,IP、子网掩码、网关都正常后,保持起来
if temp_dict.get("flag") and temp_dict.get("ip") and temp_dict.get("mask") and temp_dict.get("gateway1"):
#print("当前网卡 %s 当前适配器信息获取完毕 %s \n\n" % (temp_dict['card_name'], temp_dict))
net_card_data.append(temp_dict)
# 重置网关状态与适配器信息字典
temp_dict = dict(flag=True)
continue
pass
for i in net_card_data:
print("%s:\nip=%s,mask=%s" % (i.get("card_name"), i.get('ip'), i.get('mask')))
if __name__ == '__main__':
get_ipinfo()
结果:
7.2 使用winreg模快和netiface模块获取
注意两点
- 使用winreg取出网卡信息
- 在取该网卡的循环里使用netiface取ip,当然可以取别的我没写。可以参考前面说的neiface用法
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 文件名:getwindev.py
import netifaces
from netifaces import interfaces, ifaddresses, AF_INET
import winreg as wr
def get_ipinfo():
#获取所有网络接口卡的键值
#id = interfaces()
#存放网卡键值与键值名称的字典
key_name = {}
try:
#建立链接注册表,"HKEY_LOCAL_MACHINE",None表示本地计算机
reg = wr.ConnectRegistry(None,wr.HKEY_LOCAL_MACHINE)
# 打开r'SYSTEM\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}',固定的
reg_key = wr.OpenKey(reg , r'SYSTEM\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}')
except :
return ('路径出错或者其他问题,请仔细检查')
for ifaceName in interfaces():
try:
#尝试读取每一个网卡键值下对应的Name
reg_subkey = wr.OpenKey(reg_key , ifaceName + r'\Connection')
#如果存在Name,写入key_name字典
#print(wr.QueryValueEx(reg_subkey , 'Name')[0])
addresses = [i['addr'] for i in ifaddresses(ifaceName).setdefault(AF_INET, [{'addr':'No IP addr'}] )]
key_name[wr.QueryValueEx(reg_subkey , 'Name')[0]] = addresses[0]
except FileNotFoundError:
#print('未找到信息')
pass
return key_name
if __name__ == '__main__':
print(get_ipinfo())
结果: