今日我的Python心路历程是 初探python调试总结之互相import引发的两个窗口问题)
开门见山看问题截图如下:
很显然出现了两个一模一样的窗体,头大了。
tk_win.py代码如下:
#!/usr/bin/python
# coding=UTF-8
import tkinter as tk
#互相import产生pyc文件,且没有if __name__ == '__main__':,导致编译报错
import function
#放在函数外面会导致function.time_clock()也会调用一次窗体创建的操作
t1 = tk.Tk()
t1.title('test')
def main0():
t1.mainloop()
print('main0()')
if __name__ == '__main__':
main0()
function.py代码如下:
import time
import tk_win
def time_clock():
//此处代码无关紧要,故暂不体现
如上两个文件,一目了然二者相互import了,而且tk_win.py部分代码是全局定义的,后来折磨明白这才是重点,加上不同的title后测试效果如下描述。
title不一样,运行效果如下图所示:
代码如下:
t1 = tk.Tk()
t1.title('test')
def main0():
t1.title('main0')
t1.mainloop()
将代码和截图拼在一起看就一目了然了,两个窗体,两个title对应,这样就大体明白怎么回事了。
如上所述,问题基本清楚了,取消相互import后是正常的,但窗体文件被import后就会出现这种现象,通过现象看本质,应该是main函数体内和体外两者形成了两个实体对象所导致的差异。
故此,解决问题的方式就是统一为同一个实体对象,让大家操作一个实体对象,这样就不会发生意外了,也就是保持一致性。
优化代码后,运行效果如下图所示:
现在好多了,统一到了同一个窗体,累的我满头大汗,不寒酸上代码,tk_window.py文件代码为:
#!/usr/bin/python
# coding=UTF-8
import tkinter as tk
#互相import产生pyc文件,且没有if __name__ == '__main__':,导致编译报错
import function
import index_data
#主窗体类定义
class mainWindow:
root = None
name = '' #窗体名称
width = 0 #窗体宽度
height = 0 #窗体高度
top_frame = None
bottom_frame = None
left_frame = None
centre_frame = None
def __init__(self, name):
self.name = name
def inition(self):
self.root = tk.Tk() # 创建主窗口
# s = graphic0.Show() # Show实例化
screenWidth = self.root.winfo_screenwidth() # 获取屏幕宽的分辨率
screenHeight = self.root.winfo_screenheight()
x, y = int(screenWidth / 4), int(screenHeight / 4) # 初始运行窗口屏幕坐标(x, y),设置成在左上角显示
self.width = int(screenWidth / 2) # 初始化窗口是显示器分辨率的1.2分之一
self.height = int(screenHeight / 2)
self.root.geometry('{}x{}+{}+{}'.format(self.width, self.height, x, y)) # 窗口的大小跟初始运行位置
self.root.title(self.name) #显示主窗口1
# root.resizable(0, 0) # 固定窗口宽跟高,不能调整大小,无法最大窗口化
self.root.iconbitmap('favicon.ico') # 窗口左上角图标设置,需要自己放张图标为icon格式的图片文件在项目文件目录下
self.root.state('zoomed') # 窗口最大化处理
#设置底部栏高度,尝试几次后发现20比较合理
topHeight = 20
# 构建上方菜单栏目框架
self.top_frame = tk.Frame(self.root, width=self.width, height=topHeight, relief=tk.SUNKEN, bg='#353535', bd=5,
borderwidth=4)
self.top_frame.pack(fill=tk.BOTH, side=tk.TOP, expand=0)
# 构建底部状态栏目框架
self.bottom_frame = tk.Frame(self.root, width=self.width, height=topHeight, relief=tk.SUNKEN, bg='#353535', bd=5,
borderwidth=4)
self.bottom_frame.pack(fill=tk.BOTH, side=tk.BOTTOM, expand=0)
#函数外体被执行多次的原因是自身和import的时候也会被执行
print ('width=%d.' % self.width)
print ('height=%d.' % self.height)
print ('screenWidth0=%d.' % screenWidth)
print ('screenHeight0=%d.' % screenHeight)
#设置左部栏宽度,尝试几次后发现20比较合理
leftWidth = 20
# 构建左边功能栏目框架
self.left_frame = tk.Frame(self.root, width=leftWidth, height=self.height-topHeight*2, relief=tk.SUNKEN, bg='#353535', bd=5, borderwidth=4)
self.left_frame.pack(fill=tk.BOTH, side=tk.LEFT, expand=0)
#设置左部栏宽度,尝试几次后发现20比较合理
centerHeight = self.height - topHeight*2
# 构建中间显示栏目框架
self.centre_frame = tk.Frame(self.root, width=self.width-leftWidth, height=centerHeight, relief=tk.SUNKEN, bg='#353535', bd=5,
borderwidth=4)
self.centre_frame.pack(fill=tk.BOTH, expand=1)
# **********************************************************************************************************************
# 全局变量定义
mWin = mainWindow(u'GP量化评估分析')
# 全局变量设置结束
**********************************************************************************************************************
#窗体界面实现函数
def uiFunc():
# 构建各个框架的标签或按钮
top_label = tk.Label(mWin.top_frame, text='菜单栏目', bd=1)
top_label.pack()
bottom_label = tk.Label(mWin.bottom_frame, text='状态栏目', bd=1)
bottom_label.pack(side=tk.LEFT)
# 在状态栏目添加系统时钟功能
function.time_clock()
#定义按钮并和对应功能函数关联起来
left_button1 = tk.Button(mWin.left_frame, text='全景', bd=1, command=index_data.stockindex_function)
left_button1.pack()
# 显示主窗口2
mWin.root.mainloop()
print ('screenWidth=%d.' % mWin.width)
print ('screenHeight=%d.' % mWin.height)
#main执行入口
if __name__ == '__main__':
mWin.inition()
uiFunc()
function.py代码如下:
import time
import tk_window
def time_clock():
//此处代码无关紧要,故暂不体现
综上所述,如果在main函数体外直接写的代码会在被import的时候默认再执行一次,所以全局定义即消耗公共资源又会出问题,所以把握不好跟局部的关系,容易搞混。
参考:
1、
2、