Tôi gặp sự cố khi sử dụng các loại tín hiệu enum
. Về cơ bản, tôi có hai lớp, một máy trạng thái và một luồng xử lý máy trạng thái. Khi trạng thái được thay đổi, tôi muốn gửi tín hiệu với trạng thái mới. Tôi cũng muốn đại diện cho tiểu bang bằng cách sử dụng số enum
. Trong mã đầy đủ của tôi, máy trạng thái được thực hiện trong một thư viện chia sẻ riêng biệt, nhưng đoạn mã dưới đây đưa ra cùng một lỗi chính xác.Cách sử dụng enums trong tín hiệu và khe Qt
Khi tôi chạy mã tôi nhận được các hành vi sau đây:
[email protected]:sigenum $ ./sigenum
Object::connect: No such slot MyThread::onNewState(state)
Test signal
Test signal
...
Tôi có bốn tập tin trong mẫu mã của tôi: statemachine.h
, statemachine.cpp
, main.h
và main.cpp
. Hàm main chỉ đơn giản là bắt đầu luồng, sau đó tạo một thể hiện của StateMachine
và xử lý các tín hiệu từ StateMachine
. Tôi khá mới để Qt, vì vậy tôi là một chút bối rối khi tôi nhận ra rằng bạn phải kèm theo enum với Q_ENUMS
và đăng ký nó với hệ thống kiểu. Vì vậy, hoàn toàn có thể là tôi đã phạm một số sai lầm tân binh
Đoạn mã dưới đây hơi dài, nhưng tôi muốn nó giống như mã thực của tôi càng tốt.
statemachine.h
trông giống như:
// statemachine.h
#ifndef _STATEMACHINE_H
#define _STATEMACHINE_H
#include <QtCore>
class StateMachine : public QObject
{
Q_OBJECT
Q_ENUMS(state)
public:
enum state {S0, S1, S2};
void setState(state newState);
signals:
void stateChanged(state newState);
void testSignal(void);
};
Q_DECLARE_METATYPE(StateMachine::state);
#endif
Và nó được thực hiện như:
// statemachine.cpp
#include <QtCore>
#include "statemachine.h"
void StateMachine::setState(state newState)
{
emit stateChanged(newState);
emit testSignal();
}
Các chủ đề được định nghĩa là
// main.h
#ifndef _MAIN_H
#define _MAIN_H
#include <QtCore>
#include "statemachine.h"
class MyThread : public QThread
{
Q_OBJECT
private:
void run(void);
private slots:
void onNewState(StateMachine::state);
void onTestSignal(void);
private:
StateMachine *myStateMachine;
};
#endif
Và nó được thực hiện như sau:
// main.cpp
#include <QtCore>
#include <QApplication>
#include "statemachine.h"
#include "main.h"
void MyThread::run()
{
myStateMachine = new StateMachine();
qRegisterMetaType<StateMachine::state>("state");
// This does not work
connect(myStateMachine, SIGNAL(stateChanged(state)),
this, SLOT(onNewState(state)));
// But this does...
connect(myStateMachine, SIGNAL(testSignal()),
this, SLOT(onTestSignal()));
forever {
// ...
myStateMachine->setState(StateMachine::S0);
}
}
void MyThread::onTestSignal()
{
qDebug() << "Test signal";
}
void MyThread::onNewState(StateMachine::state newState)
{
qDebug() << "New state is:" << newState;
}
Đối với hồ sơ, lý do tại sao điều này giải quyết vấn đề là hệ thống metaobject quyết định khả năng tương thích tín hiệu/khe dựa trên các so sánh chuỗi (chuẩn hóa). Nó không "biết" rằng 'StateMachine :: state' và' state' tham chiếu đến cùng một kiểu trong ngữ cảnh này. – rohanpm
Tôi không cần qRegisterMetaType bằng cách sử dụng Qt 4.8, chỉ cần tên đủ điều kiện ở khắp mọi nơi. – kikeenrique
Có một ví dụ tương tự làm việc mà không cần gọi một cách rõ ràng 'qRegisterMetaType()' chỉ bằng cách loại bỏ dấu chấm phẩy khỏi dòng 'Q_DECLARE_METATYPE (StateMachine :: state)' – user666412