0
votes

I have a program that opens a browser frame in a specific situation, i need to be able to close it.

Im using tkinter, bellow you can find a working example. In this example i dont have any buttons but in my program i have buttons and i have it all set to to hide show frame when clicked i just need the command to close the browser since cef.shutdown() can only be used one time during the app life and the user should be able to open the browser again if he wants to.

import ctypes
import platform
from cefpython3 import cefpython as cef
from tkinter import *
import tkinter as tk
import sys
from cefpython.examples.tkinter_ import logger

WINDOWS = platform.system() == 'Windows'
LINUX = platform.system() == 'Linux'
MAC = platform.system() == 'Darwin'


class BrowserFrame(tk.LabelFrame):
    def __init__(self, master=None, **kw):
        super().__init__(master, text='Browser', **kw)
        self.browser = None
        self.bind('<Configure>', self.on_configure)

    def winfo_id(self):
        return super.winfo_id()

    def get_window_handle(self):
        if MAC:
            from AppKit import NSApp
            import objc
            return objc.pyobjc_id(NSApp.windows()[-1].contentView())
        elif self.winfo_id() > 0:
            return self.winfo_id()
        else:
            raise Exception('Could not obtain window handle!')

    def cef_loop(self):
        cef.MessageLoopWork()
        self.after(10, self.cef_loop)

    def on_configure(self, event):
        global urlset
        urlset = "http://www.google.com"
        if self.browser is None:
            # create the browser and embed it in current frame
            self.update()
            rect = [self.winfo_rootx(),self.winfo_rooty(), self.winfo_width(), self.winfo_height()]
            cef_winfo = cef.WindowInfo()
            win_id = self.get_window_handle()
            cef_winfo.SetAsChild(win_id, rect)
            self.browser = cef.CreateBrowserSync(cef_winfo, url=urlset)

            print("self: ", self)
            print("rect: ", rect)
            print("win_id: ", win_id)
            print("self.winfo_width(), self.winfo_height(): ", self.winfo_width(), self.winfo_height())

            # start the browser handling loop
            self.cef_loop()

        # resize the browser
        if WINDOWS:
            ctypes.windll.user32.SetWindowPos(
                self.browser.GetWindowHandle(), 0,
                0, 0, event.width, event.height, 0x0002)
        elif LINUX:
            self.browser.SetBounds(0, 0, event.width, event.height)


def main():
    root = tk.Tk()
    WindowUtils = cef.WindowUtils()
    sys.excepthook = cef.ExceptHook  # To shutdown all CEF processes on error
    settings = {}
    if MAC:
        settings["external_message_pump"] = True

    cef.Initialize(settings=settings)
    root.columnconfigure(0, weight=1)
    root.columnconfigure(1, weight=2)
    root.rowconfigure(0, weight=1)
    w, h = root.winfo_screenwidth(), root.winfo_screenheight()
    root.geometry("%dx%d+0+0" % (w - 250, h - 300))
    root.title('Test')

    container = Frame(root)
    canvas = tk.Canvas(container)
    scrollbar_x = Scrollbar(container, orient="horizontal", command=canvas.xview)
    scrollbar_y = Scrollbar(container, orient="vertical", command=canvas.yview)
    scrollable_frame = Frame(canvas)
    scrollable_frame.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
    canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
    canvas.configure(xscrollcommand=scrollbar_x.set)
    canvas.configure(yscrollcommand=scrollbar_y.set)

    def on_mousewheel(event):
        shift = (event.state & 0x1) != 0
        scroll = -1 if event.delta > 0 else 1
        if shift:
            canvas.xview_scroll(scroll, "units")
        else:
            canvas.yview_scroll(scroll, "units")
    canvas.bind_all("<MouseWheel>", on_mousewheel)


    leftfrm = tk.LabelFrame(scrollable_frame, text="Left", padx=5, pady=5, bg='red')
    leftfrm.grid(row=0, column=0, sticky='news', pady=2)

    home_browser = tk.LabelFrame(scrollable_frame, text="home_of_the_browser", padx=5, pady=5, bg='blue')
    home_browser.grid(row=0, column=1, pady=2, ipady=200, ipadx=400)
    home_browser.columnconfigure(1, weight=1)
    home_browser.rowconfigure(0, weight=1)

    browser_frame = BrowserFrame(home_browser)
    browser_frame.grid(row=0, column=1, sticky=('news'))
    browser_frame.columnconfigure(1, weight=1)
    browser_frame.rowconfigure(0, weight=1)
    browser_frame.pack(fill=tk.BOTH, expand=tk.YES)
    root.update()

    print("home_browser.winfo_rootx(),home_browser.winfo_rooty()",home_browser.winfo_rootx(),home_browser.winfo_rooty())
    print("->", leftfrm)  # labelframe
    print("->", home_browser)  # labelframe2
    print("->", browser_frame)  # !labelframe2.!browserframe

    for x in range(1, 25):
        tk.Label(leftfrm, text=f"Link {x}", bg='yellow').grid(row=x, column=0)

    container.pack(expand=1, fill="both")
    scrollbar_x.pack(side="bottom", fill="x")
    scrollbar_y.pack(side="right", fill="y")
    canvas.pack(side="bottom", fill="both", expand=True)

    root.mainloop()
    cef.Shutdown()
if __name__ == '__main__':
    main()