我正在设计一个GUI,PyQt当我点击一个按钮时,我需要显示一个matplotlib/pylab窗口,该按钮用于创建我创建的函数的数据图.这就像在Matlab中使用的运行时.每当我按下那个按钮时,我想保持matplotlib/pylab窗口作为我的窗口.
HY,
我正在编写我的第一个Qt程序,现在遇到麻烦:
QObject :: killTimer:无法从另一个线程停止计时器
QObject :: startTimer:无法从另一个线程启动计时器
我的程序将与CANOpen总线通信,因为我正在使用Canfestival Stack.Canfestival将使用回调方法.为了检测通信中的超时,我设置了一个定时器功能(以某种方式像看门狗).我的计时器包由"tmr"模块,"TimerForFWUpgrade"模块和"SingleTimer"模块组成."tmr"模块最初是C编程的,因此静态"TimerForFWUpgrade"方法将对其进行接口."tmr"模块将成为C程序固件更新包的一部分.
计时器将如下工作.在发送消息之前,我将调用TMR_Set方法.然后在我的空闲程序循环中使用TMR_IsElapsed我们检查定时器下溢.如果TMR_IsElapsed我会做错误处理.如您所见,将连续调用TMR_Set方法并一次又一次地重新启动QTimer.
如果我启动程序,就会出现上述错误.你能告诉我我的概念是否有效吗?为什么会出现这种错误?我是否必须在主线程中使用其他线程(QThread)?
谢谢
马特
运行和空闲循环:
void run
{
// start communicate with callbacks where TMR_Set is set continously
...
while(TMR_IsElapsed(TMR_NBR_CFU) != 1);
// if TMR_IsElapsed check for errorhandling
....
}
Run Code Online (Sandbox Code Playgroud)
模块tmr(C程序的接口):
extern "C"
{
void TMR_Set(UINT8 tmrnbr, UINT32 time)
{
TimerForFWUpgrade::set(tmrnbr, time);
}
INT8 TMR_IsElapsed(UINT8 tmrnbr)
{
return TimerForFWUpgrade::isElapsed(tmrnbr);
}
}
Run Code Online (Sandbox Code Playgroud)
模块TimerForFWUpgrade:
SingleTimer* TimerForFWUpgrade::singleTimer[NR_OF_TIMERS];
TimerForFWUpgrade::TimerForFWUpgrade(QObject* parent)
{
for(unsigned char i = 0; i < NR_OF_TIMERS; i++) …Run Code Online (Sandbox Code Playgroud) 我在"pthread vs std :: thread"和"QThread vs pthread"上看到了不同的主题,但在"std :: thread vs QThread"中没有.
我必须编写一个软件来驱动3D打印机并需要使用线程.将有一个线程将不断检查安全性,另一个用于执行打印过程,一些用于分别驱动每个硬件组件(运动,喷射......)等等...该程序是用Windows开发的C++ 11/QT.
首先我想使用QThread,但在我看来,QThread不允许你像std :: thread那样做很多东西,例如,在阅读Anthony Williams的"C++ Concurrency in Action"时,我看到它是可能的要求std :: thread通过执行类似于std::thread t1(&Class::function, this, ...);QThread似乎无法执行的操作从另一个线程执行函数.
我想拥有的机制是一种说法,如果我想在当前线程或另一个线程中执行一个函数.
您会选择哪一个以及为什么?
我正在使用QtSerialPort库通过USB与虚拟COM端口通信.COM端口返回数据并在使用QtSerialPort给出的示例项目进行测试时正常工作,但是当我将其作为项目的一部分运行时失败.
我检查了实例化链和导致QtSerialPort被实例化的线程,并发现了一些有点奇怪的东西.结果如下.
main()
MainWindow (Thread 0xbf8dbe0) // Thread "A"
HardwareManager (Thread 0xbf8dbe0) // Thread "A"
QSerialPort (Thread 0xbfb95f0) // Thread "B" !?
Run Code Online (Sandbox Code Playgroud)
在我的代码中,main()函数实例化一个MainWindow,MainWindow又实例化一个HardwareManager并将其存储为私有变量.当实例化HardwareManager时,它还实例化QSerialPort实例,以便它可以正确地与COM端口通信.
但是,您会注意到我的QSerialPort位于与父对象不同的线程中,以及它的父对象(它位于线程B中,而两个祖先都位于线程A中).我认为这个其他线程导致我的信号/插槽失败.如果我是dumpObjectInfo,它会将我的信号/插槽列为正在设置,但事件永远不会触发.
this->serial = new QSerialPort();
connect(this->serial, SIGNAL(readyRead()), this, SLOT(readSerialData());
Run Code Online (Sandbox Code Playgroud)
以上是我用来创建新串行端口并将其连接到正确插槽的代码.实际的波特率,奇偶校验和数据/停止位配置单独发生(并且正常工作,如QtSerialPort提供的示例应用程序中所测试).
有没有人知道为什么这个特定的对象(QSerialPort实例)在另一个线程中被实例化?我试过"moveToThread"来切换线程关联,但似乎没有任何效果.
编辑: 以下是调用链中的相关代码:
// main()
QApplication a(argc, argv)
MainWindow window = new MainWindow(); // [1]
MainWindow.show();
return a.exec();
// MainWindow::MainWindow() [1]
this->toolController = new QtToolController(this);
HardwareManager *manager = new HardwareManager(this->toolController); // [2]
// HardwareManager::HardwareManager() [2]
this->serial …Run Code Online (Sandbox Code Playgroud) 这是我之前发布的前一个问题的后续问题.问题是当使用NOT子类化Qthread的推荐方法时,如何从GUI停止(终止|退出)QThread,而是使用QObject然后将其移动到QThread.下面是一个工作实例.我可以启动GUI和Qthread,我可以让后者更新GUI.但是,我无法阻止它.我为qthread(quit(),exit(),甚至terminate())尝试了几种方法无济于事.非常感谢.
这是完整的代码:
import time, sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class SimulRunner(QObject):
'Object managing the simulation'
stepIncreased = pyqtSignal(int, name = 'stepIncreased')
def __init__(self):
super(SimulRunner, self).__init__()
self._step = 0
self._isRunning = True
self._maxSteps = 20
def longRunning(self):
while self._step < self._maxSteps and self._isRunning == True:
self._step += 1
self.stepIncreased.emit(self._step)
time.sleep(0.1)
def stop(self):
self._isRunning = False
class SimulationUi(QDialog):
'PyQt interface'
def __init__(self):
super(SimulationUi, self).__init__()
self.goButton = QPushButton('Go')
self.stopButton = QPushButton('Stop')
self.currentStep = QSpinBox()
self.layout = QHBoxLayout()
self.layout.addWidget(self.goButton)
self.layout.addWidget(self.stopButton) …Run Code Online (Sandbox Code Playgroud) 下面是我的qthread实现的代码.我试图从卫星获取gps数据.即使程序退出gpsSearch()插槽功能,QThread也不会产生finished()信号.locateMe()只要单击一个按钮,就会调用该函数.第一次没有启动线程并单击该按钮时,它会为isRunning()函数打印true值并为函数打印false值isFinished().我不得不调用quit()QTherad 的函数来手动停止线程.之后,它将转到类中的连接threadQuit()函数gnssProvider.但即便如此,如果我单击按钮,它会在函数中输出true isRunning和false .isFinished()locateMe()
GPSInfo::GPSInfo()
{
hybridGPSFound = satelliteGPSFound = networkGPSFound = false;
qDebug()<<"Thread Creating";
gnssThread = new QThread;
gnssProvider = new LocationFetcher(this,GEOLOCATION_PROVIDER_GNSS,1);
gnssProvider->moveToThread(gnssThread);
connect(gnssThread, SIGNAL(started()), gnssProvider, SLOT(gpsSearch()));
connect(gnssThread, SIGNAL(finished()), gnssProvider, SLOT(threadQuit()));
}
void LocationFetcher::gpsSearch()
{
if (BPS_SUCCESS != geolocation_request_events(0))
{
fprintf(stderr, "Error requesting geolocation events: %s", strerror(errno));
return;
}
geolocation_set_provider(GPS_Search_Provider);
geolocation_set_period(GPS_Search_Period);
while (!stopThread)
{
bps_event_t *event = NULL;
bps_get_event(&event, -1);
if (event) …Run Code Online (Sandbox Code Playgroud) 我有一个简单的表单UI,有一个按钮插槽,启动一个线程:
void MainWindow::LoadImage()
{
aThread->run();
}
Run Code Online (Sandbox Code Playgroud)
run()方法如下所示:
void CameraThread::run()
{
qDebug("Staring Thread");
while(1)
{
qDebug("ping");
QThread::sleep(1);
}
}
Run Code Online (Sandbox Code Playgroud)
当我单击调用LoadImage()的按钮时,UI变得无法响应.我定期看到"ping"消息作为调试输出,但UI挂起,不响应任何事情.为什么我的线程没有单独运行?CameraThread派生为公共QThread我使用gcc版本4.4.3(Ubuntu 4.4.3-4ubuntu5)与QT库和QT Creator来自Ubuntu 10.04(x86)存储库.
简而言之,我得到以下错误:
QObject::connect: Cannot queue arguments of type 'cv::Mat'
(Make sure 'cv::Mat' is registered using qRegisterMetaType().)
Run Code Online (Sandbox Code Playgroud)
我要做的是将包含两个cv :: Mat图像的信号从QThread发送到主线程,以便我可以显示输出.没有编译时错误,但是当我运行程序时,它会卡在qglobal.h(inline void qt_noop() {})的断点处.
我试图添加Q_DECLARE_METATYPE(cv::Mat)到代码,无济于事.我现在很蠢.
在QThread类中:
signals:
void sndFlow(cv::Mat &leftEye, cv::Mat &rightEye);
void eyesDriver::run()
{
forever
{
flow->draw(leftEye, rightEye);
sndFlow(leftEye, rightEye);
}
}
Run Code Online (Sandbox Code Playgroud)
捕获QObject类:
public slots:
void recFlow(cv::Mat &leftEye, cv::Mat &rightEye);
void myClass::recFlow(cv::Mat &leftEye, cv::Mat &rightEye)
{
cv::imshow("left", leftEye);
cv::imshow("rigth", rightEye);
cv::waitKey(40);
}
Run Code Online (Sandbox Code Playgroud)
主要:
Q_DECLARE_METATYPE(cv::Mat)
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qRegisterMetaType< cv::Mat >("cv::Mat");
// …Run Code Online (Sandbox Code Playgroud) 我有以下代码scan_value在更新ui(progress)中的进度条时执行后台操作().scan_value迭代某个值obj,value_changed每次更改值时发出signal().由于这里不相关的原因,我必须将它包装Scanner在另一个线程的object()中.当一个按钮扫描仪被称为scan是clicked.这是我的问题...以下代码工作正常(即进度条按时更新).
# I am copying only the relevant code here.
def update_progress_bar(new, old):
fraction = (new - start) / (stop - start)
progress.setValue(fraction * 100)
obj.value_changed.connect(update_progress_bar)
class Scanner(QObject):
def scan(self):
scan_value(start, stop, step)
progress.setValue(100)
thread = QThread()
scanner = Scanner()
scanner.moveToThread(thread)
thread.start()
scan.clicked.connect(scanner.scan)
Run Code Online (Sandbox Code Playgroud)
但如果我将最后一部分更改为:
thread = QThread()
scanner = Scanner()
scan.clicked.connect(scanner.scan) # This was at the end!
scanner.moveToThread(thread)
thread.start()
Run Code Online (Sandbox Code Playgroud)
进度条仅在最后更新(我的猜测是所有内容都在同一个线程上运行).如果在将对象接收对象移动到线程之前将信号连接到插槽,是否应该无关紧要.
我是StackOverflow的新手,想知道我是否正确行事:
我正在编写一个简单的Qt应用程序来测试多线程(我也是一个全新的东西).我创建了一个包含小部件的MainWindow,以及一个继承QThread并覆盖run()方法的类MyThread.
应用程序只显示两个按钮,"启动计数器"和"停止计数器",以及一个文本字段.当按下"启动计数器"时,创建工作线程并在后台运行,在while循环中连续递增计数器并用更新的值发信号通知主线程(GUI所在的位置).按下"停止计数器"时,会向主线程发送一个停止while循环的信号,计数器停止,直到再次按下"启动计数器".
这非常好用......但这是最好的方法吗?我是新手,并阅读了很多人说"不要继承QThread"和其他人说"子类QThread",这有点令人困惑.如果这不是实现这种事情的最佳方式(在后台线程中使用"start"和"stop"按钮运行计算密集型循环),那是什么?如果我做错了,我该怎么做呢?我不想学习错误的方法.
谢谢!这是代码:
MyThread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QMutex>
class MyThread : public QThread
{
Q_OBJECT
public slots:
void stopRunning();
protected:
virtual void run();
signals:
void signalValueUpdated(QString);
private:
bool isRunning;
};
Run Code Online (Sandbox Code Playgroud)
MyThread.cpp
#include "MyThread.h"
#include <QString>
void MyThread::run()
{
qDebug("Thread id inside run %d",(int)QThread::currentThreadId());
static int value=0; //If this is not static, then it is reset to 0 every time this function is called.
isRunning = 1;
while(isRunning == 1)
{
QString string = QString("value: …Run Code Online (Sandbox Code Playgroud) qthread ×10
c++ ×6
qt ×6
pyqt ×3
python ×3
gps ×1
matplotlib ×1
opencv ×1
pyqt4 ×1
pyside ×1
qt4 ×1
qtimer ×1
qtserialport ×1
serial-port ×1
std ×1