为什么不能同时运行tkinter mainloop和cefpython3 messageloop? [英] Why can't run both tkinter mainloop and cefpython3 messageloop?

查看:681
本文介绍了为什么不能同时运行tkinter mainloop和cefpython3 messageloop?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Python3中的一个项目中工作,在其中我同时具有tkinter和带有cef浏览器的tkinter中的框架. 这是代码.

I'm working at a project in Python3 in which i have both tkinter and a frame in tkinter with cef browser. This is the code.

from tkinter import messagebox
#import threading
from cefpython3 import cefpython as cef
import platform
import sys
from tkinter import *
import time

def on_closing ():
    print('closing')
    r.destroy()
    cef.Shutdown()

r = Tk()
r.geometry('800x600')

r.protocol('WM_DELETE_WINDOW', on_closing)

f = Frame(r, bg = 'blue', height = 200)
f.pack(side = TOP, fill = 'x')

g=Frame(r,bg = 'white',height = 200)
g.pack(side = TOP, fill = 'x')

b1 = Button (g,text='Exit',command = on_closing)
b1.pack (side = LEFT)
b2 = Button (g,text='Show something',command = lambda:messagebox.showinfo('TITLE', 'Shown something'))
b2.pack (side = RIGHT)

sys.excepthook = cef.ExceptHook

rect = [0, 0, 800, 200]
print('browser: ', rect[2],'x',rect[3])
window_info=cef.WindowInfo(f.winfo_id())
window_info.SetAsChild(f.winfo_id(),rect)
cef.Initialize()
browser = cef.CreateBrowserSync(window_info, url='http://www.google.com')

r.update()

cef.MessageLoop()
##_thread = threading.Thread(target=cef.MessageLoop)
##
##_thread.start()
##
##_thread.join()

r.mainloop()

print('end')

问题是:

  1. 我离开cef.MessageLoop(),浏览器可以工作,但按钮不起作用.
  2. 我注释掉了cef.MessageLoop(),但浏览器无法正常工作,但 tkinter窗口可以.
  1. I leave cef.MessageLoop() and the browser works but buttons don't.
  2. I comment out cef.MessageLoop() and the browser doesn't work but tkinter window does.

我在想线程模块wuold可能有帮助,但是我尝试了(您可以看到注释的行)并且不起作用(我没有例外,但浏览器不起作用). 我该如何解决呢?

I was thinking that maybe threading module wuold help but i tried (you can see the commented lines) and doesn't work (i get no exceptions but browser don't work). How can i sort this out?

推荐答案

Tkinter在单个线程中运行,因此,当您在其中编写基本上是无限循环的内容时,则会阻止Tkinter正常工作.屏幕完全出现的唯一原因是因为您使用了update(),但这不能解决这里的问题.

Tkinter runs in a single thread so when you write what is basically an infinite loop inside of it then you will block Tkinter from working. The only reason you screen is coming up at all is because you used update() but that will not fix the issue here.

解决方案是使用线程在单独的线程中管理MessageLoop,同时还将帧传递给函数,以允许Tkinter和cef之间进行某些交互.

The solution will be to use threading to manage the MessageLoop in a separate thread while also passing the frame to the function to allow for some interaction between Tkinter and cef.

注意:我也对您的代码进行了一些整理,以更好地遵循PEP8标准.

Note: I also cleaned up your code a bit to better follow PEP8 standards.

import tkinter as tk
from tkinter import messagebox
from cefpython3 import cefpython as cef
import threading
import sys


def test_thread(frame):
    sys.excepthook = cef.ExceptHook
    window_info = cef.WindowInfo(frame.winfo_id())
    window_info.SetAsChild(frame.winfo_id(), rect)
    cef.Initialize()
    browser = cef.CreateBrowserSync(window_info, url='http://www.google.com')
    cef.MessageLoop()


def on_closing():
    print('closing')
    root.destroy()


root = tk.Tk()
root.geometry('800x600')
root.protocol('WM_DELETE_WINDOW', on_closing)
frame = tk.Frame(root, bg='blue', height=200)
frame2 = tk.Frame(root, bg='white', height=200)
frame.pack(side='top', fill='x')
frame2.pack(side='top', fill='x')

tk.Button(frame2, text='Exit', command=on_closing).pack(side='left')
tk.Button(frame2, text='Show something',
          command=lambda: messagebox.showinfo('TITLE', 'Shown something')).pack(side='right')

rect = [0, 0, 800, 200]
print('browser: ', rect[2], 'x', rect[3])

thread = threading.Thread(target=test_thread, args=(frame,))
thread.start()

root.mainloop()

结果:

这篇关于为什么不能同时运行tkinter mainloop和cefpython3 messageloop?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆