我正在开发一个QT应用程序。根据我的要求,我需要创建一个Windows线程,其中我必须发出一个信号来通知位于不同类中的函数。当我试图发出一个信号时,我得到了一个错误:cannot call member function 'void Device::DataRecieved(QByteArray)' without object emit DataRecieved(Rxdata);。有没有可能从Windows线程发出QT信号。谢谢。
下面是我的代码:
DWORD WINAPI Device::RxThread(LPVOID par)
{
XLstatus xlStatus;
unsigned int msgsrx = RECEIVE_EVENT_SIZE;
XLevent xlEvent;
char tmp[100];
QString str;
g_bThreadRun = TRUE;
TStruct *g_th;
g_th = (TStruct*)par;
while(g_bThreadRun) {
WaitForSingleObject(g_th->hMsgEvent, 1000);
xlStatus = XL_SUCCESS;
while(!xlStatus) {
msgsrx = RECEIVE_EVENT_SIZE;
xlStatus = xlReceive(g_th->xlPortHandle, &msgsrx, &xlEvent);
if(xlStatus != XL_ERR_QUEUE_IS_EMPTY)
{
switch(xlEvent.tag)
{
// CAN events
case XL_SYNC_PULSE:
break;
case XL_TRANSCEIVER:
break;
// LIN events
case XL_LIN_NOANS:
break;
case XL_LIN_MSG: {
QString str1;
QString sData;
str = "RX: ";
if(xlEvent.tagData.linMsgApi.linMsg.flags & XL_LIN_MSGFLAG_TX) str = "TX: ";
str1 = "";
for(int i = 0; i<xlEvent.tagData.linMsgApi.linMsg.dlc; i++)
{
str1 = QString("%1").arg(xlEvent.tagData.linMsgApi.linMsg.data[i], 0, 16);
sData = sData + str1;
}
qDebug() << "Receiced Data is" << sData;
Rxdata.append(sData);
Device::sample();
emit DataRecieved(Rxdata);
break;
}
case XL_LIN_SLEEP:
break;
case XL_LIN_ERRMSG:
break;
case XL_LIN_SYNCERR:
break;
case XL_LIN_WAKEUP:
break;
default:
qDebug() << "Nothing found";
break;
}
ResetEvent(g_th->hMsgEvent);
}
}
}
return NO_ERROR;
}发布于 2016-04-28 20:26:04
编译器确切地告诉您问题出在哪里:DataReceived是DataReceived类的一个非静态方法,您试图在没有类实例的情况下调用它。您的emit行应该是例如emit device.DataReceived(RxData);,其中device是Device的一个实例。
由于您已经在使用Qt,因此可以将所有这些代码放入一个可以从任何线程运行的漂亮的QObject中。QThread没有什么神奇之处:它是一个指向Windows线程的句柄,没有更多,也没有更少,也没有任何开销。
这里有一个如何实现的示例。请注意,Device也可以从主线程工作,但会遭受更多的延迟。我已经为你没有显示的代码添加了占位符。
#include <QtCore>
#include <windows.h>
enum { RECEIVE_EVENT_SIZE = 128 };
enum XLstatus { XL_SUCCESS, XL_ERR_QUEUE_IS_EMPTY };
enum XLevent_tag { XL_LIN_MSG };
struct XLevent {
XLevent_tag tag;
};
typedef int XLhandle;
XLstatus xlReceive(XLhandle, unsigned int *, XLevent *) { return XL_ERR_QUEUE_IS_EMPTY; }
class Device : public QObject {
Q_OBJECT
XLhandle m_xlPortHandle;
QWinEventNotifier m_event;
HANDLE m_eventHandle;
public:
Device(QObject * parent = 0) : QObject(parent), m_eventHandle(0) {}
void open() {
// open the xl port and get the event handle
m_event.setHandle(m_eventHandle);
connect(&m_event, &QWinEventNotifier::activated, this, &Device::handler);
}
Q_SIGNAL void dataReceived(const QByteArray &);
private:
void handler() {
unsigned int msgsrx = RECEIVE_EVENT_SIZE;
XLevent xlEvent;
XLstatus xlStatus;
while (XL_SUCCESS == (xlStatus = xlReceive(m_xlPortHandle, &msgsrx, &xlEvent))) {
switch (xlEvent.tag) {
case XL_LIN_MSG: {
// ...
sample();
emit dataReceived(QByteArray());
break;
}
default:
qDebug() << "Nothing found";
break;
}
}
}
void sample() {}
};
class Thread : public QThread { using QThread::run; public: ~Thread() { quit(); wait(); } };
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Thread deviceThread;
Device device;
deviceThread.start();
device.open();
device.moveToThread(&deviceThread);
return a.exec();
}
#include "main.moc"https://stackoverflow.com/questions/36914183
复制相似问题