PyQt5 QtWebPageRenderer SIGILL问题

问题描述 投票:0回答:1

我的问题总结在标题中。当我在setHtml实例上调用方法QtWebPageRenderer时,将发出SIGILL信号,并且我的应用程序关闭。

我知道此问题是由错误的Qt5动态库引起的,但我通过以下方式安装了它:

sudo pip install PyQt5 --only-binary PyQt5
sudo pip install PyQtWebEngine --only-binary PyQtWebEngine

所以我想我会得到正确的预编译库。当我尝试不使用--only-binary安装PyQt5时,总是会遇到一些奇怪的编译错误。尽管qmake不在PATH中,但我可以从shell调用qmake

所以我的问题是,如何使PyQt5在Fedora 31上运行而没有任何SIGILL。

编辑:

以下代码可以复制该问题。关于SIGILL的信息有点不准确,因为第一个信号实际上是SIGTRAP,在gdb中单击continue后,我得到了SIGILL。这暗示了Qt实际上是想对我说些什么,尽管不是很直观。

经过一番尝试之后,我发现没有线程,就可以了。这是否意味着Qt强制用户使用QThread而不是python线程?还是这意味着我无法在运行事件循环的线程之外调用Qt对象的方法?

import signal
import sys
import threading
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5.QtWebEngineWidgets import QWebEnginePage


class WebView(QWebEnginePage):
   def __init__(self):
      QWebEnginePage.__init__(self)
      self.loadFinished.connect(self.on_load_finish)

   def print_result(self, data):
      print("-" * 30)
      print(data)
      with open("temp.html", "wb") as hndl:
         hndl.write(data.encode("utf-8"))

   def on_load_finish(self):
      self.toHtml(self.print_result)


class Runner(threading.Thread):
   def __init__(self, web_view):
      self.web_view = web_view
      threading.Thread.__init__(self)
      self.daemon = True

   def run(self):
      self.web_view.load(QtCore.QUrl("https://www.worldometers.info/coronavirus/"))


def main():
   signal.signal(signal.SIGINT, signal.SIG_DFL)
   app = QtWidgets.QApplication(sys.argv)
   web_view = WebView()
   runner = Runner(web_view)
   runner.start()
   app.exec_()


if __name__ == "__main__":
   main()
python pyqt pyqt5 fedora
1个回答
0
投票

您必须有几个限制:

  • 一个QObject不是thread-safe,因此在主线程中创建“ web_view”时,在辅助线程中对其进行修改是不安全的

  • 由于QWebEnginePage任务异步运行,因此您需要Qt事件循环。

因此,如果要使用python的Thread类,则必须同时实现这两个条件:

import signal
import sys
import threading
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5.QtWebEngineWidgets import QWebEnginePage


class WebView(QWebEnginePage):
    def __init__(self):
        QWebEnginePage.__init__(self)
        self.loadFinished.connect(self.on_load_finish)

    def print_result(self, data):
        print("-" * 30)
        print(data)
        with open("temp.html", "wb") as hndl:
            hndl.write(data.encode("utf-8"))

    def on_load_finish(self):
        self.toHtml(self.print_result)


class Runner(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True

    def run(self):
        # The QWebEnginePage was created in a new thread and 
        # that thread has an eventloop
        loop = QtCore.QEventLoop()
        web_view = WebView()
        web_view.load(QtCore.QUrl("https://www.worldometers.info/coronavirus/"))
        loop.exec_()


def main():
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    app = QtWidgets.QApplication(sys.argv)
    runner = Runner()
    runner.start()
    app.exec_()


if __name__ == "__main__":
    main()
© www.soinside.com 2019 - 2024. All rights reserved.