标签: qthread

在QThread的上下文中调用方法

在我的应用程序中有主线程和工作线程(QThread).
从主线程我想调用我的工作线程的方法,让它在线程的上下文中运行.

我已经尝试使用QMetaObject::invokeMethod并给它QueuedConnection选项,但它不起作用.
我也尝试从主线程(连接到工作线程的插槽)发出信号,但也失败了.

这是我尝试的大致的片段:

class Worker : public QThread
{
    Q_OBJECT

public:
    Worker() { }

    void run() 
    { 
        qDebug() << "new thread id " << QThread::currentThreadId(); 
        exec(); 
    }

public slots:
    void doWork()
    {
        qDebug() << "executing thread id - " << QThread::currentThreadId();
    }
};
Run Code Online (Sandbox Code Playgroud)

使用QMetaObject方式:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << "main thread id - " << QThread::currentThreadId();

    Worker worker;
    worker.start();

    QMetaObject::invokeMethod(&worker, "doWork", Qt::QueuedConnection);

    return a.exec();
}
Run Code Online (Sandbox Code Playgroud)

使用信号方式: …

c++ qt multithreading qthread

6
推荐指数
1
解决办法
7696
查看次数

在QThread中调用QThread.exec()方法是必要的吗?

我没有exec()在我的代码中调用,但是timer并且QUdpSocket工作正常.被exec()用于等待的event继续吗?

更新:timer工作正常,因为我没有打电话moveToThread(this)QThread,这意味着它QThread实际上仍然是其中的一部分main thread.至于QUdpSocket我使用投票functions.所以它不需要合作signals.

提示:如果你需要做init一些东西,那需要event loop你的QThread,你可以delay打电话,moveToThread直到你不再需要它signals,这在程序加载时是实用的.您也不需要在构造函数中调用它run()(例如,您可以在内部调用它),只需将this QThread指针复制到变量并call使用指针在其他地方/其他地方生成.

qt multithreading qthread

6
推荐指数
1
解决办法
1万
查看次数

PyQt4导致QThread错误

使用PyQt4 4.8.6,下面的代码会产生错误

QObject :: startTimer:QTimer只能用于以QThread启动的线程

当a用作QApplication的变量时,如果cpp(或大多数其他)用于变量,它不会产生错误.这是PyQt4中的错误还是我缺少的东西?

#! /usr/bin/env python

# This is only needed for Python v2 but is harmless for Python v3.
import sip
sip.setapi('QVariant', 2)

from PyQt4 import QtGui

#def main():

if __name__ == '__main__':
    import sys

    if len(sys.argv) > 1:
       use_a = False
       print "Don't use a"
    else:
       use_a = True
       print "Use a"

    if use_a:
       a = QtGui.QApplication(sys.argv)
    else:
       cpp = QtGui.QApplication(sys.argv)

    model = QtGui.QStandardItemModel(4,2)
    tableView = QtGui.QTableView()
    tableView.setModel(model)

    tableView.show()
    if use_a:
       sys.exit(a.exec_())
    else:
       sys.exit(cpp.exec_())


#if …
Run Code Online (Sandbox Code Playgroud)

python pyqt pyqt4 qthread qtimer

6
推荐指数
1
解决办法
1117
查看次数

暂停并恢复QThread

我最近开始学习QThreads,我有一个程序在一个单独的线程中运行4个小时的循环(这样我可以继续使用GUI).我所追求的是,​​当用户点击暂停qpushbutton时暂停/暂停线程的东西,当用户点击恢复qpushbutton时,程序应该恢复.我怎么能实现这个目标?

我正在考虑从我的主班发送信号; 但是,我不确定如何在线程中处理它们.是否可以处理线程中主类发送的信号?目前,我有线程向主类发出信号,并且工作正常,但我不知道如何从主类发送线程,并在线程中接收它们.

qt4 visual-studio-2010 qthread

6
推荐指数
1
解决办法
7901
查看次数

PyQt-在GUI中运行循环

我有一个内部带有while循环的Python代码,但是我不知道如何使其与我的PyQt GUI一起工作-我只能运行Qt窗口或该循环(但窗口不会显示)。有什么解决办法吗?我读了一些QThreads或QTimers,但我不知道如何使用它。

python pyqt qthread

6
推荐指数
1
解决办法
1万
查看次数

如果没有正确的wait()调用关闭应用程序,QThread会发生什么?

在下面的示例中(在Qt GUI应用程序中)启动了一个新线程(带有一个事件循环,我希望在其中完成一些工作):

void doWork()
{
   QThread* workerThread = new QThread();

   Worker* worker = new Worker();
   worker->moveToThread(workerThread);

   connect(workerThread, SIGNAL(started()), worker, SLOT(startWork()));
   connect(worker, SIGNAL(finished()), workerThread, SLOT(quit()));

   connect(workerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
   connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));

   workerThread->start();
}
Run Code Online (Sandbox Code Playgroud)

startWork() 可以是一个长时间运行的操作,在此期间可以关闭应用程序.

我希望只要在应用程序startWork()上执行应用程序就不会关闭workerThread.但是,当我关闭最后一个应用程序窗口时,它workerThread会立即消失(在长时间运行期间)并且应用程序关闭没有问题.

问题出现了:

  1. 为什么立即workerThread擦拭?
    • 这是一些父母/子女问题吗?
    • Qt如何处理这种情况?
  2. 这是程序员的错误,而不是调用wait()QThread(最终)?
    • 即使这样,我也试着wait()进入一个插槽,aboutToQuit()并且在长时间运行操作完成后应用程序没有关闭(如上所述设置).仅quit(); wait();(在提到的插槽内)允许应用程序关闭.为什么?

c++ qt multithreading worker qthread

6
推荐指数
1
解决办法
1598
查看次数

正确使用QThread.currentThreadId()

我认为确定QThread当前运行函数的ID 是QThread.currentThreadId().但是我发现这没有给出预期的结果(在PyQt5中使用python 3;但是我没有理由相信它与pyqt4/py 2不同,因此通用标签).线程ID以我无法解释的方式变化,表明我实际上无法使用它,QThread实例id可预测地变化,表明我应该使用它来识别当前正在运行的线程.为了测试,我创建了这个:

from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import pyqtSignal
import time
import sys

def logthread(caller):
    print('%-25s: %s, %s' % (caller, QtCore.QThread.currentThread(), QtCore.QThread.currentThreadId()))


class Worker(QtCore.QObject):
    done = pyqtSignal()

    def __init__(self, parent=None):
        logthread('worker.__init__')
        super().__init__(parent)

    def run(self, m=10):
        logthread('worker.run')
        for x in range(m):
            y = x + 2
            time.sleep(0.001) 
        logthread('worker.run finished')

        self.done.emit()


class MainWindow(QtWidgets.QWidget):
    def __init__(self, parent=None):
        logthread('mainwin.__init__')
        super().__init__(parent)

        self.worker = Worker()
        self.workerThread = None

        self.btn = QtWidgets.QPushButton('Start worker in thread')
        self.btn2 = QtWidgets.QPushButton('Run worker …
Run Code Online (Sandbox Code Playgroud)

python multithreading pyqt qthread

6
推荐指数
1
解决办法
5129
查看次数

Pyinstaller无法与线程一起正常工作

运行bat文件的程序,其中包含使用Qthread运行可执行文件(longTask)的指令,但是当我使用Pyinstaller通过以下命令创建可执行文件时,该程序无法按预期工作。我给“ --windowed”提供了标准I / O的控制台窗口

pyinstaller --onefile --windowed main.py

但是有趣的是,当我删除--windowed参数时,它可以按预期工作

pyinstaller --onefile main.py
Run Code Online (Sandbox Code Playgroud)

这是代码:

from PyQt4.Qt import *
import subprocess


def callSubprocess():
    page = QWizardPage()
    page.setTitle("Run myLongTask")

    runButton = QPushButton("Run")
    progressBar = QProgressBar()
    procLabel = QLabel()
    procLabel1 = QLabel()
    progressBar.setRange(0, 1)

    layout = QGridLayout()
    layout.addWidget(runButton, 0, 0)
    layout.addWidget(progressBar, 0, 1)
    layout.addWidget(procLabel)
    layout.addWidget(procLabel1)

    # Calls thread class
    myLongTask = TaskThread()
    runButton.clicked.connect(lambda: OnStart(myLongTask, progressBar, procLabel1))
    myLongTask.taskFinished.connect(lambda: onFinished(progressBar, procLabel))
    page.setLayout(layout)
    return page


def OnStart(myLongTask, progressBar, procLabel1):
    progressBar.setRange(0, 0)
    myLongTask.start()
    # I am waiting until …
Run Code Online (Sandbox Code Playgroud)

python pyinstaller pyqt4 qthread

6
推荐指数
1
解决办法
1098
查看次数

循环QProgressBar给出错误>> QObject :: installEventFilter:无法过滤不同线程中对象的事件

这个问题似乎已经多次以多种不同形式提出,但我没有找到一个与我的代码解决方案相关的问题.

当我运行它显示的程序时

QObject :: installEventFilter:无法过滤不同线程中对象的事件.

尽管如此,代码最初工作,但一段时间后炸弹和python发出错误说它停止工作.

我的代码如下:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from xml.etree import ElementTree as ET
import os , time

class LayoutCreator(QDialog):
    def __init__(self , parent=None):
        super(LayoutCreator, self).__init__(parent)
        self.Cameras_Update()


    def Cameras_Update( self ):                                             # Get all shots with camera plots and add them to the cameras_tree
        busyBar = sqrl_QtTools.BusyBar( text = "Gathering Camera Data" )    # Looping progress bar
        busyBar.start()

        # loop through folder structure storing data                

        busyBar.Kill()                                                      # Close looping progress bar    


class BusyBar(QThread): …
Run Code Online (Sandbox Code Playgroud)

pyqt qprogressbar qthread qobject

5
推荐指数
1
解决办法
3688
查看次数

暂停和恢复 QThread

我正在尝试暂停 QThread 并恢复它。

所以,我在 QThread 中有一个 RFID 读取循环,我想在读取器获得 RFID 代码时暂停无限循环。之后,进行数据库检查。在检查结束时,我想恢复 RFID 读取循环以获取其他代码。

MVCE:

def main():
    global Thread
    app = QtGui.QApplication(sys.argv)
    main = Main()
    Thread = RFID_Thread()
    Thread.rfid_event.connect(Main().on_event)
    Thread.start()
    sys.exit(app.exec_())

class Main(object):
    def __init__(self):
        self.accueil = MainWindow(self)
        self.access = AccessWindow()
        self.accueil.show()

    def on_event(self, data):
        # I WANT TO PAUSE THE QTHREAD HERE

        ###################################
        #   CHECKING DB & SHOWING UI      #
        ###################################

        # AND RESUME IT HERE
class RFID_Thread(QtCore.QThread):
    rfid_event = pyqtSignal(str, name='rfid_event')
    def run(self):
        while 1:
            ser = serial.Serial(port=Serial_Port, baudrate=Serial_Baudrate)
            a …
Run Code Online (Sandbox Code Playgroud)

python pyqt pyqt4 qthread

5
推荐指数
1
解决办法
7000
查看次数