yjg30737 / pyqt-frameless-window

PyQt(+PySide) Frameless Window
MIT License
36 stars 5 forks source link

QWebEngineView view breaks most of the window functionality #8

Open ArthurNRL opened 1 year ago

ArthurNRL commented 1 year ago

When adding QWebEngineView to the central widget layout the resize and snap functionality stops working. I'm using windows if that helps. Minimal code to reproduce:

class MainWindow(QMainWindow, BaseWidget):

    def __init__(self, hint=None):
        super().__init__()
        self._initVal()
        self._initUi(hint)

    def _initUi(self, hint):
        super()._initUi(hint)
        lay = QVBoxLayout()
        lay.addWidget(self._titleBar)
        lay.setContentsMargins(0, 0, 0, 0)
        lay.setSpacing(0)

        lay.addWidget(QWebEngineView())

        mainWidget = QWidget()
        mainWidget.setLayout(lay)

        self.setCentralWidget(mainWidget)
yjg30737 commented 1 year ago

I assume you are using Windows 10.

I did this in Windows 10 as well but as you said it didn't work at all. To me, resizing/moving/snap feature works well, but web view and title bar is invisible for some reasons. isVisible returns True in any event i caught, so i don't understand why this happen.

This is my test sample code

import sys

from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView

from pyqt_frameless_window import FramelessMainWindow
from PyQt5.QtWidgets import QApplication

class MainWindow(FramelessMainWindow):

    def __init__(self):
        super().__init__()
        self.__initUi()

    def __initUi(self):
        self.setWindowTitle('QWebEngineView window')

        webView = QWebEngineView()
        webView.setUrl(QUrl('https://www.google.com/maps/?hl=en'))

        mainWidget = self.centralWidget()
        lay = mainWidget.layout()
        lay.addWidget(webView)
        mainWidget.setLayout(lay)

        self.setCentralWidget(mainWidget)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

I'm trying to solve this problem in Windows 10 on my virtual machine.

btw For some reasons, in Windows 11, it works just fine

image

yjg30737 commented 1 year ago

I did the previous test in Window 10 and 11 with PyQt5.

I assume you did it with PySide6. That actually shows the view, but there is no Windows effect and resizing feature is not available, like you said.

I'm still working on it.

yjg30737 commented 1 year ago

I searched how to do that and i know something:

The QWebEngineView widget uses Chromium to render web pages, which is a separate process from the main PyQt application. This means that the QWebEngineView widget has its own window handle and its own message loop, which may not be fully in sync with the main PyQt window. This can cause issues with the resizing and snap feature of Windows, as the Windows operating system may not be able to properly detect and handle the resizing and snap events for the QWebEngineView widget.

Additionally, The QWebEngineView widget may also disable the customized title bar's features such as dragging, resizing and snap feature for security reasons.

TL;DR it is not supposed to use with win32 application, which is pyqt-frameless-window using currently in Windows.

If you want to implement the web engine, then you have to use the regular title bar.

If you want to implement web page only (not script) you can use the QTextEdit with setHtml method.

If you want to show the web engine with customized title bar like Chrome, you can make the Electron app.

In the PyQt desktop application at least.

By the way, i tried qml as well but it doesn't work either.

ArthurNRL commented 1 year ago

That's sad to hear, we are porting a python/pyside2 to pyside6 and front end in react using webengine. We've tried electron but it's too much of a resource hog(and also need to include node and chrome in the bundle to work) for our requirements, the webengine does exactly what we need while keeping resources to a minimum.

Did PyQt5 work on windows 11? If so we'll probably look into purchasing a license

yjg30737 commented 1 year ago

PyQt works on Windows 11, QWebEngineView with customized title bar works like a charm on Windows 11.

ArthurNRL commented 1 year ago

Would you be able to describe the problem so I can try to create an issue in the PySide issue tracker?

yjg30737 commented 1 year ago

Yes. I will definitely do it.

But i can't do it in weekend because vmware pro which i tested the app for Windows 10 installed in my pc in workplace, and i can't install it in my pc at home because of disk capacity.

Please wait till Monday or Tuesday. I will take the picture and video (if it can) to explain this problem. My English skill is quite limited so i'm not sure i can describe well by only text.

ArthurNRL commented 1 year ago

Thanks! You can post it here and I'll try to proofread

yjg30737 commented 1 year ago

Code sample

import sys

from PySide6.QtCore import QUrl
from PySide6.QtWebEngineWidgets import QWebEngineView

from pyqt_frameless_window import FramelessMainWindow
from PySide6.QtWidgets import QApplication, QTextEdit, QWidget, QPushButton, QVBoxLayout

class WebEngineView(QWebEngineView):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

class MainWindow(FramelessMainWindow):

    def __init__(self):
        super().__init__()
        self.__initUi()

    def __initUi(self):
        self.setWindowTitle('QWebEngineView window')

        self.__webView = WebEngineView()
        self.__webView.setUrl(QUrl('https://www.google.com/maps/?hl=en'))

        btn = QPushButton('Add Web View')
        btn.clicked.connect(self.__addView)

        self.__innerWidget = QWidget()
        innerWidgetLay = QVBoxLayout()
        self.__innerWidget.setLayout(innerWidgetLay)

        mainWidget = self.centralWidget()
        lay = mainWidget.layout()
        lay.addWidget(btn)
        lay.addWidget(QTextEdit())
        mainWidget.setLayout(lay)

        self.setCentralWidget(mainWidget)

    def __addView(self):
        lay = self.__innerWidget.layout()
        lay.addWidget(self.__webView)
        self.layout().addWidget(self.__innerWidget)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

Result

Result 1

https://user-images.githubusercontent.com/55078043/215623301-513f8cbd-acee-4bbe-8fef-4c7d16fcbef6.mp4

Result 2

https://user-images.githubusercontent.com/55078043/215623733-12f16f92-d8d2-4689-9a74-ce40d22d4958.mp4

yjg30737 commented 1 year ago

Windows 10 Pro version 22H2 in vmware

ArthurNRL commented 1 year ago

Thanks. I as soon as I can I'll create an issue!

yjg30737 commented 1 year ago

It was my pleasure :)

ArthurNRL commented 1 year ago

I've created a issue: https://bugreports.qt.io/browse/PYSIDE-2248

yjg30737 commented 1 year ago

Many thanks to you 😥😥😥😥👍👍👍👍

ArthurNRL commented 1 year ago

Hey, I've managed to get snapping to work(some code in the pyside issue), though I had to make my own side/corner draggable grips and titlebar drag using systemMove/Resize

yjg30737 commented 1 year ago

Great! Best wish to you :)