簡體   English   中英

Python PyQt5 從另一個 Py 文件添加列表項

[英]Python PyQt5 Add List Item from another Py-File

單擊 PyQt5 Ui iam 中的按鈕時,我正在啟動 mitmproxy。 啟動代理時,我嘗試使用代理中的數據更改 listWidget。

main.py

    import sys
    
    from PyQt5 import QtWidgets
    from PyQt5.QtWidgets import QApplication, QMainWindow
    from MainWindow import Ui_MainWindow
    
    class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    
        def __init__(self, *args, obj=None, **kwargs):
            super(MainWindow, self).__init__(*args, **kwargs)
            self.setupUi(self)
    
            self.pushButton.clicked.connect(self.Start)
    
        def Start(self):
            x = threading.Thread(target=self.StartMITM)
            x.start()
    
        def StartMITM(self):
            os.system("mitmweb -s mitmproxy.py -q --no-web-open-browser")
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        win = MainWindow()
        win.show()
        sys.exit(app.exec_())

mitmproxy.py - 這是錯誤部分

    from mitmproxy import http
    from main import MainWindow
    
    def response(flow):
        MainWindow.listWidget.addItem(flow.request.pretty_url)

我可以從另一個文件連接到小部件嗎?

它有 2 個獨立的進程:GUI 和 mitmproxy 腳本。 並且通信兩個進程並不意味着導入模塊,因為您將創建另一個小部件,也不應該通過類訪問對象(我建議您檢查基本的 python 注釋)。

在這種情況下,解決方案是使用一些進程間通信(IPC),在這種情況下,您可以使用Qt 遠程對象(QtRO)

主文件

from functools import cached_property

from PyQt5 import QtCore, QtRemoteObjects, QtWidgets


class Bridge(QtCore.QObject):
    messageChanged = QtCore.pyqtSignal(str)

    @QtCore.pyqtSlot(str)
    def add_message(self, message):
        self.messageChanged.emit(message)


class MitmwebManager(QtCore.QObject):
    logChanged = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)
        # self.process.setProcessChannelMode(QtCore.QProcess.MergedChannels)
        self.process.readyReadStandardOutput.connect(self.handle_log)
        self.process.setProgram("mitmweb")

    @cached_property
    def process(self):
        return QtCore.QProcess()

    def start(self, arguments):
        self.process.setArguments(arguments)
        self.process.start()

    def stop(self):
        self.process.kill()

    def handle_log(self):
        data = self.process.readAllStandardOutput()
        codec = QtCore.QTextCodec.codecForName("UTF-8")
        message = codec.toUnicode(data)
        self.logChanged.emit(message)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.button = QtWidgets.QPushButton("Start", checkable=True)
        self.listwidget = QtWidgets.QListWidget()
        self.logview = QtWidgets.QPlainTextEdit(readOnly=True)

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        lay = QtWidgets.QGridLayout(central_widget)
        lay.addWidget(self.button, 0, 0, 1, 2)
        lay.addWidget(self.listwidget, 1, 0)
        lay.addWidget(self.logview, 1, 1)

        self.register_node = QtRemoteObjects.QRemoteObjectRegistryHost(
            QtCore.QUrl("local:registry")
        )
        self.source_node = QtRemoteObjects.QRemoteObjectHost(
            QtCore.QUrl("local:replica"), QtCore.QUrl("local:registry")
        )
        self.source_node.enableRemoting(self.bridge, "bridge")

        self.button.toggled.connect(self.handle_toggled)
        self.mitmweb.logChanged.connect(self.handle_log_changed)
        self.bridge.messageChanged.connect(self.handle_message_changed)

        self.resize(640, 480)

    @cached_property
    def mitmweb(self):
        return MitmwebManager()

    @cached_property
    def bridge(self):
        return Bridge()

    def handle_toggled(self, checked):
        if checked:
            self.mitmweb.start(["-s", "script.py", "--no-web-open-browser"])
            self.button.setText("Stop")
        else:
            self.mitmweb.stop()
            self.button.setText("Start")

    def handle_log_changed(self, message):
        self.logview.insertPlainText(message)

    def closeEvent(self, event):
        super().closeEvent(event)
        self.mitmweb.stop()

    def handle_message_changed(self, message):
        item = QtWidgets.QListWidgetItem(message)
        self.listwidget.addItem(item)


def main():
    app = QtWidgets.QApplication([])

    view = MainWindow()
    view.show()

    app.exec_()


if __name__ == "__main__":
    main()

腳本.py

from mitmproxy import http

from PyQt5 import QtCore, QtRemoteObjects


class Bridge(QtCore.QObject):
    def __init__(self, bridge, parent=None):
        super().__init__(parent)
        self._message = ""
        self._bridge = bridge

        self.bridge.initialized.connect(self.handle_initialized)

    @property
    def bridge(self):
        return self._bridge

    @property
    def message(self):
        return self._message

    def send_message(self, message):
        self._message = message

    @QtCore.pyqtSlot()
    def handle_initialized(self):
        self.bridge.add_message(self._message)
        QtCore.QTimer.singleShot(0, QtCore.QCoreApplication.quit)


def send_qt(message):
    qt_app = QtCore.QCoreApplication([])
    replica_node = QtRemoteObjects.QRemoteObjectNode(QtCore.QUrl("local:registry"))
    replica_bridge = replica_node.acquireDynamic("bridge")
    bridge = Bridge(replica_bridge)
    bridge.send_message(message)
    qt_app.exec_()


def response(flow):
    send_qt(flow.request.pretty_url)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM