引言
在使用TinUI编写轻型浏览器中,我们使用我的tkwebview2作为网页控件,搭建了一个轻型浏览器。
在使用中,一定会发现,输入框在我们点击任意一个WebView2控件后都会失效,也就是无法再一次获取输入。需要让整个窗口失去焦点,才能再次激活tkinter输入框。
这种情况很麻烦,但是最近我找到了解决办法——以毒攻毒,直接将WinForms的TextBox控件“tkinter化”,替代tkinter输入框。
测试文件——tkwebview2/001.py at main · Smart-Space/tkwebview2 · GitHub。
解决思路
其实通过测试,我们可以发现在点击webview2控件后,输入框不能直接点击输入内容。
这个示例在早期的
tkwebview2/001.py
中。
发现以下信息:
-
在tkinter单独使用若干个WinForms控件,不会造成WinForms输入框失效。
我们不需要在同一个Frame里面添加多个WinForms控件,我们仅需要分别将WinForms控件转为tkinter控件使用就可以了。
-
点击TextBox控件之后,tkinter输入框也失效
不单单是WebView2的问题,而是全部winforms控件的问题。
解决方法
很简单,就是用TextBox代替Entry控件。接下来就是两种方法:
-
将Entry作为父组件,填充布局(字号字体一致,通过
TextBox.Font
设置) -
覆盖Entry布局(字号字体一致)
将TextBox转为tkinter控件代码:
def tofont(name:str,size:int):
return Font(String(name),Single(size))
#tkinter化winforms的textbox
class tkTextBox(Frame):
def __init__(self,master,width=400,height=20):
Frame.__init__(self,master,width=width,height=height)
font=tofont('微软雅黑',14)
self.tb=TextBox()
self.ehwnd=int(str(self.tb.Handle))
user32.SetParent(self.ehwnd,self.winfo_id())
user32.MoveWindow(self.ehwnd,0,0,width,height,True)
self.tb.Font=font
self.bind('<Configure>',self.__resize)
def __resize(self,event):
self.tb.Width=self.winfo_width()
self.tb.Height=self.winfo_height()
def get(self):
return self.tb.Text
tofont
函数是将python中的字体字号转化为WinForms控件可用的Font
类
如果需要改动字体,则使用如下代码:
tktextbox.tb.Font=tofont('font-name',size)
具体解决
上面提出了解决方法,那么具体情况呢?接下来以开头提到文章里面的代码做示例。
主要改动的地方,就是在newpage
函数中,使用tkTextBox
覆盖。
def newpage(title='新标签页',url='https://bing.com/'):
#...
__urlenter,uid = nx.tags["urlenter"]
bbox=nu.bbox(uid)
urlenter=tkTextBox(nu)
nu.create_window((bbox[0],bbox[1]),window=urlenter,anchor='nw',
width=bbox[2]-bbox[0],height=bbox[3]-bbox[1])
urlenter.tb.KeyDown+=lambda s,a:newurl(s,a,webview)
重写newurl
函数。
def newurl(s,e,wb):
if e.KeyCode==Keys.Enter:
url=s.Text
if url!='':
wb.load_url(url)
效果
结语
到这里,tkinter中使用winforms控件导致输入框失效的问题就解决了。
🔆tkinter创新🔆
【笔记】