wxWidgets / Phoenix

wxPython's Project Phoenix. A new implementation of wxPython, better, stronger, faster than he was before.
http://wxpython.org/
2.28k stars 514 forks source link

Calling a webview from pywebview is breaking a wxpython GUI #2586

Closed Chen-Michael closed 1 week ago

Chen-Michael commented 4 weeks ago

Operating system: windows 10 wxPython version & source: wxPython>=4.0 Python version & source: 3.9

Description of the problem:

import wx
import wx.html2
import webview

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        super(MyFrame, self).__init__(*args, **kwds)
        # Create a button
        self.button = wx.Button(self, label="Open WebView")
        self.button.Bind(wx.EVT_BUTTON, self.on_button_click)

    def on_button_click(self, event):
        # This function is called when the button is clicked
        # Create and show the WebView dialog
        auth_url = "https://google.com"
        window = webview.create_window("Access example", auth_url)
        webview.start()

if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame(None)
    frame.Show()
    app.MainLoop()
reticulatus commented 3 weeks ago

When webview.start() is called it enters its own event loop and doesn't return until its window has been closed, thus blocking your wxPython application.

Is there a special reason for not using html2.WebView which is designed to work with wxPython?

import wx
import wx.html2

class Browser(wx.Dialog):
    def __init__(self, *args, **kwds):
        super().__init__(*args, **kwds)
        self.SetSize((480, 530))
        self.webview = wx.html2.WebView.New(self)

    def loadURL(self, title, url):
        self.SetTitle(title)
        self.webview.LoadURL(url)
        if not self.IsShown():
            self.Show()

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        super(MyFrame, self).__init__(*args, **kwds)
        # Create a button
        self.button = wx.Button(self, label="Open WebView")
        self.button.Bind(wx.EVT_BUTTON, self.on_button_click)
        self.browser = Browser(self, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)

    def on_button_click(self, event):
        # This function is called when the button is clicked
        # Show the browser dialog
        url = "https://google.com"
        self.browser.loadURL("Access example", url)

if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame(None)
    frame.Show()
    app.MainLoop()
Chen-Michael commented 2 weeks ago

When webview.start() is called it enters its own event loop and doesn't return until its window has been closed, thus blocking your wxPython application.

Is there a special reason for not using html2.WebView which is designed to work with wxPython?

import wx
import wx.html2

class Browser(wx.Dialog):
    def __init__(self, *args, **kwds):
        super().__init__(*args, **kwds)
        self.SetSize((480, 530))
        self.webview = wx.html2.WebView.New(self)

    def loadURL(self, title, url):
        self.SetTitle(title)
        self.webview.LoadURL(url)
        if not self.IsShown():
            self.Show()

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        super(MyFrame, self).__init__(*args, **kwds)
        # Create a button
        self.button = wx.Button(self, label="Open WebView")
        self.button.Bind(wx.EVT_BUTTON, self.on_button_click)
        self.browser = Browser(self, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)

    def on_button_click(self, event):
        # This function is called when the button is clicked
        # Show the browser dialog
        url = "https://google.com"
        self.browser.loadURL("Access example", url)

if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame(None)
    frame.Show()
    app.MainLoop()

bc, use html2.WebView I can't clear Microsoft login status

I try use JS clear cookies, localstorage...etc, restart app then open WebView always catch login status

but since this is maintaining someone else's project, I don't know what he did to cause this

reticulatus commented 2 weeks ago

I don't use Windows so I can't help with the Microsoft issue.

I seem to remember reading somewhere of a technique for running two event loops in the same process using python's asyncio module. However, I've not been able to find it again.

As an alternative, could your wxPython app run a simple webview script in a child process?

Chen-Michael commented 2 weeks ago

I don't use Windows so I can't help with the Microsoft issue.

I seem to remember reading somewhere of a technique for running two event loops in the same process using python's asyncio module. However, I've not been able to find it again.

As an alternative, could your wxPython app run a simple webview script in a child process?

We has communicated with the users and they can accept their own operation to log out.

tks

infinity77 commented 1 week ago

@swt2c : I believe this one can be closed.