Python学习(7)--获取windows本地网卡和地址信息(2)

5 控件combobox

也就是下拉框

下拉框的主要用法就是:

  1. 创建下拉的内容
  2. 选定下拉内容

由于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类型。所以需要对这个类型多多学习和理解。请参考Python 字典(Dictionary) | 菜鸟教程

7 获取本机网卡信息

7.1 使用re模块对命令行解析获取

用到的内容:

  1. subpross.Popen()执行ipconfig命令
  2. 对ipconfig得到的字符串进行正则匹配拿到想要的结果
  3. 分两层解析: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模块获取

注意两点

  1. 使用winreg取出网卡信息
  2. 在取该网卡的循环里使用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())

结果:

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值