Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在pyqt pyside中同时运行一个对象的多个实例_Python_Pyqt_Pyside_Qthread - Fatal编程技术网

Python 如何在pyqt pyside中同时运行一个对象的多个实例

Python 如何在pyqt pyside中同时运行一个对象的多个实例,python,pyqt,pyside,qthread,Python,Pyqt,Pyside,Qthread,在下面的代码中,您可以在每次单击“新建”按钮时打开新选项卡,每个选项卡都包含QWebView浏览器(在PyQt/PySide中使用)和“开始”按钮,当“开始”按钮单击浏览器时,逐个加载3个站点 问题是: 当打开多个选项卡并运行所有选项卡或多个选项卡时,所有其他选项卡将暂停加载,直到最后一个选项卡完成加载,然后继续下一个选项卡 我想同时运行它们如何 import sys from PySide.QtGui import * from PySide.QtCore import * from PySi

在下面的代码中,您可以在每次单击“新建”按钮时打开新选项卡,每个选项卡都包含QWebView浏览器(在PyQt/PySide中使用)和“开始”按钮,当“开始”按钮单击浏览器时,逐个加载3个站点 问题是: 当打开多个选项卡并运行所有选项卡或多个选项卡时,所有其他选项卡将暂停加载,直到最后一个选项卡完成加载,然后继续下一个选项卡 我想同时运行它们如何

import sys
from PySide.QtGui import *
from PySide.QtCore import *
from PySide.QtWebKit import *


class Main_Gui(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        layout = QVBoxLayout()
        self.bt_new = QPushButton('New')
        self.tabwidget = QTabWidget()
        layout.addWidget(self.tabwidget)
        layout.addWidget(self.bt_new)
        self.setLayout(layout)
        self.bt_new.clicked.connect(self.add_new)

    def add_new(self):
        br = browser()
        self.tabwidget.addTab(br, 'browser')


class browser(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        layout = QVBoxLayout()
        self.br = QWebView()
        self.bt_Start = QPushButton('Start')
        layout.addWidget(self.br)
        layout.addWidget(self.bt_Start)
        self.setLayout(layout)
        self.bt_Start.clicked.connect(self.start_load)

    def start_load(self):
        self.th = QThread()
        self.th.started.connect(self.load)
        self.th.start()

    def load(self):
        sites = ['https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/'
            , 'http://www.codecademy.com/tracks/python', 'http://www.google.com']
        for i in sites:
            self.br.load(QUrl(i))
            self.sleep(20)

    def sleep(self, seconds):
        end = QTime.addSecs(QTime.currentTime(), seconds)
        while end > QTime.currentTime():
            QCoreApplication.processEvents()


app = QApplication(sys.argv)
win = Main_Gui()
win.resize(800, 600)
win.show()
sys.exit(app.exec_())

您没有为
QThread
s分配任何工作(不要重新实现
run
方法)
browser.load
slot,您已经连接了
th.started
signal,它在主线程中执行(因为您的浏览器是在其中创建的)。这导致了你的问题

此外,您可以仅从主线程更改GUI(例如调用
self.br.load
方法)(为了线程安全)


感谢Alexander,他为我在问题中提交的示例提供了线索和完整代码,问题是我想告诉QThread等待页面加载,我找到了一个解决方案,在QThread中创建一个名为loaded的局部变量,并将浏览器loadFinished信号连接到函数,使加载的变量在加载完成时为true,在QThread中,我创建了等待代码,直到loaded var变为true

import sys
from PySide.QtGui import *
from PySide.QtCore import *
from PySide.QtWebKit import *
from Browser_AutoPilot import BrowserAutoPilot


class Main_Gui(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        layout = QVBoxLayout()
        self.bt_new = QPushButton('New')
        self.tabwidget = QTabWidget()
        layout.addWidget(self.tabwidget)
        layout.addWidget(self.bt_new)
        self.setLayout(layout)
        self.bt_new.clicked.connect(self.add_new)

    def add_new(self):
        br = browser()
        self.tabwidget.addTab(br, 'browser')


class browser(QWidget):
    load_finished = Signal()

    def __init__(self):
        QWidget.__init__(self)
        layout = QVBoxLayout()
        self.br = BrowserAutoPilot()
        self.bt_Start = QPushButton('Start')
        layout.addWidget(self.br)
        layout.addWidget(self.bt_Start)
        self.setLayout(layout)
        self.th = TimerThread()
        self.bt_Start.clicked.connect(self.start_load)

    def start_load(self):
        self.stop_thread(self.th)

        self.th.nextURL.connect(self.load_url_slot)
        self.br.loadFinished.connect(self.wait_loading)
        self.th.start()

    def load_url_slot(self, url):
        self.br.load(QUrl(url))

    def wait_loading(self):
        self.th.loaded = True

    def stop_thread(self, thread):
        thread.terminate()
        if thread.isRunning():
            QCoreApplication.processEvents()

    def sleep(self, seconds):
        end = QTime.addSecs(QTime.currentTime(), seconds)
        while end > QTime.currentTime():
            QCoreApplication.processEvents()


class TimerThread(QThread):
    nextURL = Signal(str)

    def __init__(self, loaded=False):
        QThread.__init__(self)
        self.loaded = loaded

    def run(self):
        sites = ['https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/',
                 'http://www.codecademy.com/tracks/python', 'http://www.google.com']

        for url in sites:
            print(self.thread(), url)
            self.nextURL.emit(url)
            self.loaded = False
            while not self.loaded:
                self.sleep(1)

app = QApplication(sys.argv)
win = Main_Gui()
win.resize(800, 600)
win.show()
sys.exit(app.exec_())

这很好,但我仍然有一个问题,我想告诉Qthread等待页面加载不是确定的时间,实际上我想知道如何向TimerThread发送通知,webview已完成加载,您可以进行下一个循环迭代并发出第二个信号
import sys
from PySide.QtGui import *
from PySide.QtCore import *
from PySide.QtWebKit import *
from Browser_AutoPilot import BrowserAutoPilot


class Main_Gui(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        layout = QVBoxLayout()
        self.bt_new = QPushButton('New')
        self.tabwidget = QTabWidget()
        layout.addWidget(self.tabwidget)
        layout.addWidget(self.bt_new)
        self.setLayout(layout)
        self.bt_new.clicked.connect(self.add_new)

    def add_new(self):
        br = browser()
        self.tabwidget.addTab(br, 'browser')


class browser(QWidget):
    load_finished = Signal()

    def __init__(self):
        QWidget.__init__(self)
        layout = QVBoxLayout()
        self.br = BrowserAutoPilot()
        self.bt_Start = QPushButton('Start')
        layout.addWidget(self.br)
        layout.addWidget(self.bt_Start)
        self.setLayout(layout)
        self.th = TimerThread()
        self.bt_Start.clicked.connect(self.start_load)

    def start_load(self):
        self.stop_thread(self.th)

        self.th.nextURL.connect(self.load_url_slot)
        self.br.loadFinished.connect(self.wait_loading)
        self.th.start()

    def load_url_slot(self, url):
        self.br.load(QUrl(url))

    def wait_loading(self):
        self.th.loaded = True

    def stop_thread(self, thread):
        thread.terminate()
        if thread.isRunning():
            QCoreApplication.processEvents()

    def sleep(self, seconds):
        end = QTime.addSecs(QTime.currentTime(), seconds)
        while end > QTime.currentTime():
            QCoreApplication.processEvents()


class TimerThread(QThread):
    nextURL = Signal(str)

    def __init__(self, loaded=False):
        QThread.__init__(self)
        self.loaded = loaded

    def run(self):
        sites = ['https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/',
                 'http://www.codecademy.com/tracks/python', 'http://www.google.com']

        for url in sites:
            print(self.thread(), url)
            self.nextURL.emit(url)
            self.loaded = False
            while not self.loaded:
                self.sleep(1)

app = QApplication(sys.argv)
win = Main_Gui()
win.resize(800, 600)
win.show()
sys.exit(app.exec_())