简体   繁体   中英

TypeError: QWebEngineView(parent: QWidget = None): argument 1 has unexpected type 'PySide2.QtWidgets.QFrame'

I'm currently trying to embed a QtWebEngine in my PyQT5 script using a promoted QtWidget, but I can't get it to work properly.

This is my code:

import sys
import os
import platform
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import (QCoreApplication, QPropertyAnimation, QDate, QDateTime, QMetaObject, QObject, QPoint, QRect, QSize, QTime, QUrl, Qt, QEvent)
from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont, QFontDatabase, QIcon, QKeySequence, QLinearGradient, QPalette, QPainter, QPixmap, QRadialGradient)
from PySide2.QtWidgets import *
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets, uic

# UI File
from harvester_ui import Window
from ui_functions import * 


class Window(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Window()
        self.ui.setupUi(self)


        self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
        
        self.ui.minimize.clicked.connect(lambda: self.showMinimized())
        self.ui.close.clicked.connect(app.exit)
        
        def moveWindow(w): 
            if w.buttons() == Qt.LeftButton:  
                self.move(self.pos() + w.globalPos() - self.clickPosition)
                self.clickPosition = w.globalPos()
                w.accept()

        self.ui.label.mouseMoveEvent = moveWindow

        self.show()

    def mousePressEvent(self, event):
        self.clickPosition = event.globalPos()

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    sys.exit(app.exec_())

If I try to execute this code, I get the error showed in the title.

If I replace the last lines with these, it will work properly, but it won't function as I want it as my changes are stored in the class.

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    path_ui = os.path.join(os.path.dirname(__file__), "window.ui")
    window = uic.loadUi(path_ui)
    window.browser.load(QtCore.QUrl("https://google.com/"))
    window.show()
    sys.exit(app.exec_())

My goal is to be able to embed the browser instance directly from the class that I'm using, instead of doing it in the if statement.

Despite being almost identical bindings to Qt, PyQt and PySide should never be used together. Most problems rise when trying to reparent a widget created with a binding with another created with the other binding, like in your case.

The solution is simple: you either use PyQt5 or PySide2.

When using files generated with the uic tool ( pyuic for PyQt, pyside2-uic for PySide), it is mandatory to use the related binding. If pyuic (which is the PyQt tool) was used, then the imports must use PyQt5; if the files were generated with pyside2-uic , then PySide2 must be used instead.

You should also be more careful when importing, as different "levels" of import might lead to confusion.

For example, in your case, the following line will result in having QtWidgets.QMainWindow imported from PySide

from PySide2 import QtCore, QtGui, QtWidgets

The following makes QMainWindow use the PySide version too:

from PySide2.QtWidgets import *

This will override the first import, which will make QtWidgets.QMainWindow use the PyQt version instead:

from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets, uic

With the above import statements, the result is that QtWidgets.QMainWindow will be from PyQt5, while QMainWindow will be from PySide2 (and the same for all other classes of each of those sub modules).
Even ignoring the fact that those two modules should never be used together, having the same class names imported from different modules is a severe semantic issue that would most certainly lead to bugs.

Using coherent import styles (at least when importing from the same main module) is usually preferable. Take, for instance, the following lines:

from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import (QCoreApplication, QPropertyAnimation, QDate, QDateTime, QMetaObject, QObject, QPoint, QRect, QSize, QTime, QUrl, Qt, QEvent)
from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont, QFontDatabase, QIcon, QKeySequence, QLinearGradient, QPalette, QPainter, QPixmap, QRadialGradient)
from PySide2.QtWidgets import *

They are related but different import styles, but the most important thing is that the explicit imports (second and third line) and the wildcard import of the last line make almost useless the first one.
Consider that while in python it's normally preferred to be explicit (see Zen of Python ), every rule has its exception, and in the case of very large modules like Qt it can become very uncomfortable to have a continuously growing list of explicit imports, also considering that during production some classes might become unused, but still unnecessarily imported because they were never removed from the import.

Since the performance difference during loading is usually negligible, using the submodule import is normally preferable (instead of explicit or wildcard imports): it avoids a possibly really long import statement (as the explicit would), and it also makes more clear from what submodule a class has been loaded.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM