我在python中遇到QThreads的问题.我想改变标签的背景颜色.但我的应用程序在启动时崩溃."QThread:在线程仍在运行时被破坏"
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
statusTh = statusThread(self)
self.connect(statusTh, SIGNAL('setStatus'), self.st, Qt.QueuedConnection)
statusTh.start()
def st(self):
if self.status == 'ON':
self.ui.label.setStyleSheet('background-color:green')
else:
self.ui.label.setStyleSheet('background-color:red')
class statusThread(QThread):
def __init__(self, mw):
super(statusThread, self).__init__()
def run(self):
while True:
time.sleep(1)
self.emit(SIGNAL('setStatus'))
if __name__ == "__main__":
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud) 我试图在特定的线程中启动QTimer.但是,计时器似乎没有执行,也没有打印出来.是与计时器,插槽还是线程有关?
main.cpp中
#include "MyThread.h"
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
MyThread t;
t.start();
while(1);
}
Run Code Online (Sandbox Code Playgroud)
MyThread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QTimer>
#include <QThread>
#include <iostream>
class MyThread : public QThread {
Q_OBJECT
public:
MyThread();
public slots:
void doIt();
protected:
void run();
};
#endif /* MYTHREAD_H */
Run Code Online (Sandbox Code Playgroud)
MyThread.cpp
#include "MyThread.h"
using namespace std;
MyThread::MyThread() {
moveToThread(this);
}
void MyThread::run() {
QTimer* timer = new QTimer(this);
timer->setInterval(1);
timer->connect(timer, SIGNAL(timeout()), this, SLOT(doIt()));
timer->start();
}
void MyThread::doIt(){
cout …Run Code Online (Sandbox Code Playgroud) QThreads和QRunnable有什么区别?
什么时候应该使用QThread和QRunnable?
在我的Qt应用程序中,我有一个主线程和一个工作线程.工作线程QThread通过子类和处理事件customEvent.这是主线程发送工作线程处理事件的正确方法吗?
QThread* myWorkerThread = // ...
QApplication::instance()->postEvent (myWorkerThread, new MyWorkRequestEvent(/* ... */);
Run Code Online (Sandbox Code Playgroud)
如果我正确阅读文档,它会声明事件是在拥有事件收件人的对象的线程上处理的.由于QThread是由主线程创建的,它由主线程拥有 - 所以这个事件会被主线程处理(这会违反直觉,在我的情况下会是错误的)?
我试图在我的PySide GUI应用程序中做一个相当常见的事情:我想将一些CPU密集型任务委托给后台线程,以便我的GUI保持响应,甚至可以在计算进行时显示进度指示器.
这是我正在做的事情(我在Python 2.7,Linux x86_64上使用PySide 1.1.1):
import sys
import time
from PySide.QtGui import QMainWindow, QPushButton, QApplication, QWidget
from PySide.QtCore import QThread, QObject, Signal, Slot
class Worker(QObject):
done_signal = Signal()
def __init__(self, parent = None):
QObject.__init__(self, parent)
@Slot()
def do_stuff(self):
print "[thread %x] computation started" % self.thread().currentThreadId()
for i in range(30):
# time.sleep(0.2)
x = 1000000
y = 100**x
print "[thread %x] computation ended" % self.thread().currentThreadId()
self.done_signal.emit()
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
self.work_thread = QThread()
self.worker = Worker()
self.worker.moveToThread(self.work_thread) …Run Code Online (Sandbox Code Playgroud) 假设您的应用程序需要在多个线程中运行一个函数,其数量大于CPU核心/线程的数量.一种方法是使用QtConcurrent和设置最大线程数:
MyClass *obj = new MyClass;
QThreadPool::globalInstance()->setMaxThreadCount(30);
for(int i=0;i<30;i++)
QtConcurrent::run(obj, &MyClass::someFunction);
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用多个对象并将它们移动到不同的线程moveToThread:
for(int i=0;i<30;i++)
{
MyClass *obj = new MyClass;
QThread *th = new QThread();
obj->moveToThread(th);
connect(th, SIGNAL(started()), obj, SLOT(someFunction()) );
connect(obj, SIGNAL(workFinished()), th, SLOT(quit()) );
connect(th, SIGNAL(finished()), obj, SLOT(deleteLater()) );
connect(th, SIGNAL(finished()), th, SLOT(deleteLater()) );
th->start();
}
Run Code Online (Sandbox Code Playgroud)
由于线程数大于CPU核心数,因此在运行时应该在不同的核心之间切换线程.
问题是这两种方法是否有不同的表现?即,切换是否QThread与使用QtConcurrent::run?的切换不同?
我有以下代码:
class A : public QObject
{
Q_OBJECT
public:
A() : QObject()
{
moveToThread(&t);
t.start();
}
~A()
{
t.quit();
t.wait();
}
void doSomething()
{
QMetaObject::invokeMethod(this,"doSomethingSlot");
}
public slots:
void doSomethingSlot()
{
//do something
emit ready();
}
signals:
void ready();
private:
QThread t;
}
Run Code Online (Sandbox Code Playgroud)
问题为什么doSomething必须通过它来调用QMetaObject::invokeMethod.我知道连接类型有一些东西.有人可以解释引擎盖下的内容吗?
是否可以设置主GUI线程的优先级,以便与其他线程(QThread)相比具有更高的优先级?
我的目标是在其他线程进行一些密集计算时不冻结GUI,这可能会占用CPU到100%的负载.如果有人可以分享一种方法来确保GUI在此期间不会冻结,而其他计算线程仍然可以尝试最大化CPU使用率,那将是很棒的.
我考虑过管理其他线程,所以我不会同时启动太多的计算线程.
我为gstreamer创建了一个单独的类来传输视频.
该类使用moveToThread()在单独的线程上运行.
我正在使用Qt5.5进行开发.
当我在主线程上发出startcommand时,Qthread启动并且gstreamer用于g_main_loop_run流式传输视频.这绝对没问题.但不知何故g_main_loop_run阻止线程,当我发出信号从主线程停止视频时,它不会在gstreamer类中执行插槽.
有人可以建议我如何解决这个问题?我可以用其他g_main_loop_r命令替换un或者可以使用g_main_loop_quit( gloop ); 用另一种方式.
void StreamingVideo::slotStartStream() // this slot called on start of thread from main thread
{
if( !isElementsLinked() )
{
qDebug() << " we are emitting in dummy server ";
//emit sigFailed( "elementsFailed" ); // WILL CONNECT IT WITH MAIN GUI ONXCE CODE IS FINISHED
return;
}
gst_bus_add_watch( bus, busCall, gloop );
gst_object_unref( bus );
//proper adding to pipe
gst_bin_add_many( GST_BIN( pipeline ), source, capsFilter, conv, …Run Code Online (Sandbox Code Playgroud) 我试着这样做:
connect(this, SIGNAL(signalClicked(int&)), classA, SLOT(doWork(int&)));
Run Code Online (Sandbox Code Playgroud)
但我在标题中得到了消息.所以我已经探索了互联网,我想出了这个不起作用的解决方案:
qRegisterMetaType<int&>("Type");
connect(this, SIGNAL(signalClicked(Type)), classA, SLOT(doWork(Type)));
Run Code Online (Sandbox Code Playgroud)
(错误:没有用于调用'qRegisterMetaType(const char [5])'的匹配函数)
有解决方案吗 谢谢你的帮助.