[CEFPython3]弹出窗口的解决

前言

这段时间研究了cefpython3,发现了一个问题,就是说点击链接时会弹出一个子窗口。看到网上没有相应的教程,就发出来了

思路

在C++的版本看到,有一个函数OnBeforePopup可以搞定,但cefpython并不一样,于是查阅官方文档PYPI在github的帮助文档里Quick links的API Index中找到:

在这里插入图片描述

在这里插入图片描述
GitHub接口说明

解释

interface是接口,要用browser.SetClientHandler设置,传入对象,cef会在相应事件发生时调用(可多次使用)。

#例子(代码段)
class LoadHandler():#类名不一定是这个
  def OnBeforePopup(self,target_url,**_):#只需要target_url参数,其他关键字参数不要
    print(target_url)#一些处理
    return True#返回True值就不弹出
window_info = cef.WindowInfo()
browser = cef.CreateBrowserSync(window_info,url=url)
browser.SetClientHandler(LoadHandler())#传入对象,注意是对象不是类
#TODO:剩余代码

一个tkinter的绑定

直接运行得到一个简易浏览器,导入得到Browser类,当tkinter.Frame使用
可传入参数url
只要覆盖NewWindow方法,接受位置参数url并返回小写的"break"即可
默认已经是在原frame中打开,而test中是用ttk.notebook新标签页打开

from cefpython3 import cefpython as cef
import tkinter as tk
import platform
WINDOWS = (platform.system() == "Windows")
LINUX = (platform.system() == "Linux")
MAC = (platform.system() == "Darwin")
# Fix for PyCharm hints warnings
WindowUtils = cef.WindowUtils()

cef.Initialize() #init
class Browser(tk.Frame):
    class LoadHandler(object):
        def __init__(self, browser):
            self.browser = browser
        def OnBeforePopup(self,target_url,**a):
            res = self.browser.NewWindow(target_url)
            if res == "break":
                return True
    class FocusHandler(object):
        "From cefpython3.example.tkinter_"
        def __init__(self, browser_frame):
            self.browser_frame = browser_frame
        def OnSetFocus(self, source, **_):
            return False
        def OnGotFocus(self, **_):
            """Fix CEF focus issues (#255). Call browser frame's focus_set
               to get rid of type cursor in url entry widget."""
            self.browser_frame.focus_set()
    def __init__(self,*a,url="",**b):
        super().__init__(*a,**b)
        #create browser
        window_info = cef.WindowInfo()
        rect = [0, 0, self.winfo_width(), self.winfo_height()]
        window_info.SetAsChild(self.get_window_handle(), rect)
        if not url:
            url="https://www.baidu.com/"
        self.browser = cef.CreateBrowserSync(window_info,url=url)
        assert self.browser
        self.browser.SetClientHandler(self.LoadHandler(self))
        self.browser.SetClientHandler(self.FocusHandler(self))
        #fit frame
        self.bind("<Configure>", self._configure)
    def _configure(self, event):
        res=self.event_generate("<<Configure>>")
        if res=="break":
            return
        width = event.width
        height = event.height
        if WINDOWS:
            WindowUtils.OnSize(self.winfo_id(), 0, 0, 0)
        elif LINUX:
            self.browser.SetBounds(0, 0, width, height)
        self.browser.NotifyMoveOrResizeStarted()
    def NewWindow(self,url):
        self.load(url)
        return "break"
    def loadurl(self,url):
        self.browser.StopLoad()
        self.browser.LoadUrl(url)
    def geturl(self):
        return self.browser.GetUrl()
    def reload(self):
        self.browser.Reload()
    def get_window_handle(self):
        "From cef"
        if self.winfo_id() > 0:
            return self.winfo_id()
        elif MAC:
            # On Mac window id is an invalid negative value (Issue #308).
            # This is kind of a dirty hack to get window handle using
            # PyObjC package. If you change structure of windows then you
            # need to do modifications here as well.
            # noinspection PyUnresolvedReferences
            from AppKit import NSApp
            # noinspection PyUnresolvedReferences
            import objc
            # Sometimes there is more than one window, when application
            # didn't close cleanly last time Python displays an NSAlert
            # window asking whether to Reopen that window.
            # noinspection PyUnresolvedReferences
            return objc.pyobjc_id(NSApp.windows()[-1].contentView())
        else:
            raise Exception("Couldn't obtain window handle")     
def maincefloop(n=200):
    cef.MessageLoopWork()
    tk._default_root.after(n, maincefloop,n)
def bye():
    cef.Shutdown()
def test():
    def makenew(url):
        b = Browser(note,url=url)
        note.add(b,text=url.replace("https://","").replace("http://","").replace("blob://","")[:25])
        note.select(note.index("end")-1)
        b.NewWindow=lambda url:makenew(url) or "break"
    from tkinter import ttk
    root = tk.Tk()
    note = ttk.Notebook()
    note.pack(expand=1,fill="both")
    makenew("https://www.baidu.com")
    root.title("cefweb.Browser")
    root.geometry("800x600")
    maincefloop()
    root.mainloop()
    bye()
if __name__ == "__main__":
    test()

注释懒得写了,都是cef官方example给的,文档也很详细,就不多写了

总结

文档会看吗?
不要吝啬你的赞!

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值