我使用的是 PySide 版本 1.2.2,它包装了 Qt v4.8 框架。QThread我面临的情况是,我必须在让我的应用程序等待我不再需要正常退出的情况(线程很可能会无限期地阻塞)和给无响应的线程一个宽限期(几秒钟)之间做出选择),然后调用QThread.terminate()它。尽管我希望可以,QThread但当底层线程仍在运行时,我不能让对象超出范围,因为这会抛出错误“QThread:线程仍在运行时被销毁”,并且几乎肯定会导致段错误。
请注意,我知道终止QThreads 是危险的并且强烈建议不要这样做。我只是想在这里探索我的选择。
然而,当我尝试终止线程时,我的应用程序崩溃并出现以下错误:
Python 致命错误:释放时该线程状态必须是当前状态
您可以通过复制/粘贴并运行以下代码自行尝试:
from PySide import QtCore, QtGui
class Looper(QtCore.QThread):
"""QThread that prints natural numbers, one by one to stdout."""
def __init__(self, *args, **kwargs):
super(Looper, self).__init__(*args, **kwargs)
self.setTerminationEnabled(True)
def run(self):
i = 0
while True:
self.msleep(100)
print(i)
i += 1
# Initialize and start a looper.
looper = Looper()
looper.start()
# Sleep main thread for 5 seconds.
QtCore.QThread.sleep(5)
# Terminate …Run Code Online (Sandbox Code Playgroud) 我正在尝试暂停 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) 我真的很难理解如何在 PyQt 中使用线程。我做了一个简单的例子来说明我想在用户界面中做什么。在下面的代码中,我希望用户输入股票行情(例如,您可以输入“bby”、“goog”或“v”)并绘制特定时期内股票的价值。问题是在更复杂的用户界面中,或者在很长一段时间内,用户界面在绘图更新时冻结。所以我制作了一个“绘图仪”类,当它收到某个信号时更新绘图(覆盖 Qthread.run 显然不是你做错的正确方法)。我想让这个“绘图仪”在主线程之外的另一个线程中运行。
一旦我取消注释线程,程序就会停止工作。我尝试移动新线程的启动以及“连接”,但没有任何效果。我认为即使在阅读了文档并查看了 Qt 网站上的示例之后,我仍然不太理解 Qthread 的工作原理。
如果您知道如何做到这一点,那将会有很大帮助!(我正在使用 Python 3.5 和 PyQt5)
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from matplotlib.axes._subplots import Axes
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import sys
from datetime import datetime, timedelta
import time
import quandl
class MyMplCanvas(FigureCanvas):
"""Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
send_fig = pyqtSignal(Axes, str, name="send_fig")
def __init__(self, parent=None):
self.fig = Figure()
self.axes = self.fig.add_subplot(111)
# …Run Code Online (Sandbox Code Playgroud) 这是我在使用PyQT时遇到的最大麻烦:我已经为我的应用程序拼了一个缩略图线程(我必须缩略图大量的图像),看起来它会工作(而且几乎可以).每当我SIGNAL从我的线程发送一个时,我的主要问题是这个错误消息:
QPixmap: It is not safe to use pixmaps outside the GUI thread
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚如何解决这个问题.我试过QIcon通过我的SIGNAL,但仍然会产生相同的错误.如果它有帮助,这里是处理这些东西的代码块:
本Thumbnailer类:
class Thumbnailer(QtCore.QThread):
def __init__(self, ListWidget, parent = None):
super(Thumbnailer, self).__init__(parent)
self.stopped = False
self.completed = False
self.widget = ListWidget
def initialize(self, queue):
self.stopped = False
self.completed = False
self.queue = queue
def stop(self):
self.stopped = True
def run(self):
self.process()
self.stop()
def process(self):
for i in range(self.widget.count()):
item = self.widget.item(i)
icon = QtGui.QIcon(str(item.text()))
pixmap = icon.pixmap(72, …Run Code Online (Sandbox Code Playgroud) 目前我有一些麻烦将QVector传递给线程.目前我有一个主线程(GUI-Thread)和一个频繁发出QVector数组的工作线程.直接在向量内部发射数据之前看起来很好.接收器是主线程中的一个插槽,但是插槽接收的数据是乱码.
以下是我的代码的一些部分:
在工作线程中发出:
void Pipeline::process
{
QVector<float> buffer(w * h * d);
// filling the vector with RGB-Values
emit this->pushBuffer(buffer, w, h, d);
}
Run Code Online (Sandbox Code Playgroud)
主线程中信号和插槽的连接:
QObject::connect(this->_pipeline.data(), SIGNAL(pushBuffer(const QVector<float>, int, int, int)), this->ui->widgetFiltered, SLOT(setBuffer(const QVector<float>,int,int,int)));
Run Code Online (Sandbox Code Playgroud)
主线程中的插槽:
void GLWidget::setBuffer(const QVector<float> buffer, int dataSizeX, int dataSizeY, int dataSizeZ)
{
// at this point the contents inside 'buffer' is garbled
}
Run Code Online (Sandbox Code Playgroud)
Thread通过使用QObject的moveToThread启动,并QVector<float>通过qRegisterMetaType< QVector<float> >("QVector<float>");main方法注册到元系统.
Pipeline::process返回后数据是否可能丢失?我不确定QVector这个多线程情况下隐式共享内部的行为如何.
任何帮助,将不胜感激.
问候
狼
我需要使用按钮非常频繁地启动和停止线程..我正在使用Qt.最近我学会了创建一个worker的QObject并将其移动到QThread的对象,作为在Qt中实现线程的正确方法.以下是我的实施......
Worker.h
class worker : public QObject
{
Q_OBJECT
public:
explicit worker(QObject *parent = 0);
void StopWork();
void StartWork();
bool IsWorkRunning();
signal:
void SignalToObj_mainThreadGUI();
public slots:
void do_Work();
private:
void Sleep();
volatile bool running,stopped;
QMutex mutex;
QWaitCondition waitcondition;
};
Run Code Online (Sandbox Code Playgroud)
Worker.cpp
worker::worker(QObject *parent) :
QObject(parent),stopped(false),running(false)
{
}
void worker::do_Work()
{
running = true;
while(!stopped)
{
emit SignalToObj_mainThreadGUI();
Sleep();
}
}
void worker::Sleep()
{
mutex.lock();
waitcondition.wait(&mutex,10);
mutex.unlock();
}
void worker::StopWork()
{
mutex.lock();
stopped = true;
running = false;
mutex.unlock();
}
void worker::StartWork() …Run Code Online (Sandbox Code Playgroud) 我想在QThread中运行一个计时器.我写了一些代码,其中我在运行时遇到了一些错误.请引导我走向正确的方向.我究竟做错了什么?
(Parent is QThread(0x1498d10), parent's thread is QThread(0x11272b0), current thread is QThread(0x1498d10)
Run Code Online (Sandbox Code Playgroud)
mainwindow.h //主.h文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "mythread.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
MyThread *myt;
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
Run Code Online (Sandbox Code Playgroud)
mainwindow.cpp //主.cpp文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
myt=new MyThread();
myt->start();
MainWindow w;
}
MainWindow::~MainWindow()
{
delete ui;
}
Run Code Online (Sandbox Code Playgroud)
mythread.h //线程类
#ifndef MYTHREAD_H …Run Code Online (Sandbox Code Playgroud) 我有一个3个QThreads彼此调用(所有都继承自QThread.我知道有些人可能建议使用moveToThread,但现在暂时忽略这个事实).简化代码如下所示:
Thread1类:
void
Thread1::run
{
// some execution
Thread2 t2 = new Thread2();
connect(t2,SIGNAL(finished),this,SLOT(onFinished));
t2->start();
while(!stop) // stop was initialized as false
{
this->msleep(10);
}
}
void Thread1::onFinished(){ stop = true; }
Run Code Online (Sandbox Code Playgroud)
Thread2类:
void
Thread2::run
{
// some execution
Thread3 t3 = new Thread3();
connect(t3,SIGNAL(finished),this,SLOT(onFinished));
t3->start();
while(!stop) // stop was initialized as false
{
this->msleep(10);
}
}
void Thread2::onFinished(){ stop = true; }
Run Code Online (Sandbox Code Playgroud)
Thread3类:
void
Thread3::run
{
// some execution
QMutexLocker ml(&mMutex);
}
Run Code Online (Sandbox Code Playgroud)
当我只有两个线程时,它完全正常(例如,只有thread2和thread3).在我转移到三线程场景之后,onFinished()方法似乎不再正确连接finished()信号.已经调用了thread2中的onFinished().而且我很确定thread3的执行已经完成.
谁能告诉我哪里可能做错了?
我正在尝试创建一个新的线程gpsthread,它应该在后台运行,并存储该值.
class gpsthread: public QThread{
Q_OBJECT
private:nrega_status_t status2;
public:
explicit gpsthread(QObject *parent = 0):QThread(parent) {
// QTimer *t = new QTimer(this);
// connect(t, SIGNAL(timeout()), this, SLOT(processgps()));
// t->start(10000);
}
void run(){
qDebug()<<"inside gps thread\n";
QTimer *t = new QTimer(this);
connect(t, SIGNAL(timeout()), this, SLOT(processgps()));
t->start(10000);
}
public slots:void processgps(){
int status2;
status2=gps_management();
}
};
Run Code Online (Sandbox Code Playgroud)
我的主要课程是quickview.
int main(int argc, char *argv[])
{
QString file = "qml/main.qml";
QApplication app(argc, argv);
TranslationTest myObj;
QuickView view;
subthread object;
gpsthread obj;
gprsthread gprs;
view.rootContext()->setContextProperty("rootItem", (QObject *)&myObj); …Run Code Online (Sandbox Code Playgroud) 我做过这样的事情:
//in the mainwindow's constructor
QThread *thr = new QThread;
soundWorker * work = new soundWorker;
connect(this,SIGNAL(playsound()),work,SLOT(process()));
work->moveToThread(thr);
thr->start();
Run Code Online (Sandbox Code Playgroud)
我应该删除thr并在mainwindow的解构器中工作吗?