I have been writing a window tool for image sensor calibrations, it basically has these functions: a UI for interacting with users, a communication module responsible for communications between client and server, finally a module to represent the sensor’s attributes and the necessary calibration methods.
I decided to implement it as a Qt custom widget plugin so it could be further integrated.
I created the custom widget project using Qt Creator which was sweet because it generated all the necessary files and project settings for me. Everything’s swift until I began to add the communication and calibration functionalities to my widget class.
Here’s the widget plugin class generated:
#include <QDesignerCustomWidgetInterface>
class sDeltaWidgetPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface")
#endif // QT_VERSION >= 0x050000
public:
sDeltaWidgetPlugin(QObject *parent = 0);
bool isContainer() const;
bool isInitialized() const;
QIcon icon() const;
QString domXml() const;
QString group() const;
QString includeFile() const;
QString name() const;
QString toolTip() const;
QString whatsThis() const;
QWidget *createWidget(QWidget *parent);
void initialize(QDesignerFormEditorInterface *core);
private:
bool m_initialized;
};
And the widget class I exported:
class QDESIGNER_WIDGET_EXPORT sDeltaWidget : public QWidget
{
Q_OBJECT
public:
explicit sDeltaWidget(QWidget *parent = 0);
~sDeltaWidget();
private:
Ui::sDeltaWidget *ui;
public:
bool online;
protected:
sDeltaCom* com;
sensor_polisher* polisher;
public slots:
void connect_server(QHostAddress&, u16&);
};
Regarding above class, member com is an object of class sDeltaCom(the class for communications), member polisher is an object of class sensor_polisher(the class for sensor calibrations), and a slot connect_server.
Further, class sDeltaCom as below:
class sDeltaCom: public QObject, public MetaPoint
{
Q_OBJECT
public:
sDeltaCom();
~sDeltaCom();
public:
QHostAddress server_addr;
u16 server_port;
QTcpSocket tcpsocket;
QDataStream datastream;
public:
bool estab_connection(QHostAddress& addr, u16& port);
bool send(Message* msg);
//bool received_and_notify(Message*);
private slots:
void processMsg();
void processSocketError(QAbstractSocket::SocketError);
public slots:
void msg_err_handler(Message*);
void fin_msg_handler(Message*);
signals:
void msg_sync_ok(Message* msg);
void msg_config_ok(Message* msg);
void msg_collect_ok(Message* msg);
void msg_timing_ok(Message* msg);
void msg_error(Message* msg);
};
Then class MetaPoint:
class MetaPoint {
public:
MetaPoint();
~MetaPoint();
public:
static u16 SysEndian;
bool connected;
virtual bool estab_connection() { return false; }
virtual bool wait_connect() { return false; }
virtual bool send(Message*) { return false; }
virtual bool received_and_notify(Message*) { return false; }
virtual void destroyMsg(Message*);
static Message* assembleMsg(const u8& MsgId, const u16& len, const u8* data);
static void preSend(Message* msg);
static void preProcessRcvdMsg(Message* msg);
static void top_ntoh(Message*);
static void top_hton(Message*);
static bool push_tagged_data(Message* msg, const u8& tag, u16& bytelen, const u8* data);
static bool pop_tagged_data(Message* msg, u8& tag, u16& bytelen, u8* data);
static bool push_data(Message* msg, const u8* data, const u16& bytelen);
static bool pop_data(Message* msg, u8* data, u16& bytelen);
static u16 SysEndianess();
static u16 u16_swap(u16&);
static u32 u32_swap(u32&);
static u64 u64_swap(u64&);
static u16 SysU16(u16& data, u16& MsgEndian);
static u32 SysU32(u32& data, u16& MsgEndian);
static u64 SysU64(u64& data, u16& MsgEndian);
};
class MetaPoint is not a child of QObject, because I what it to be a generic communication end point which provides common message data operations, and some other interfaces.
Basically that’s all the stuff, I built the widget plugin as an shared library successfully and it appeared in my Qt Designer side window.
My Questions:
Q1 when I build the window application linking this plugin, I got undefined reference linker error: “undefined reference to `sDeltaWidget::sDeltaWidget(QWidget*)’”, seems linker cant find the widget class’s constructor symbol, but using nm -C -D I could see that this symbol has been exported. My .pro file has been added into this line: LIBS +=/opt/Qt5.0.2/5.0.2/gcc/plugins/designer/libsdeltawidgetplugin.so, so ld should be able to find the library. Anyone knows why? Please help.
Q2 Another question, when I simply add interfaces(normal class member functions, non-slot-or-signal) to the widget class sDeltaWidget, I could not find those interfaces’ symbols in the generated library file, it seems those interfaces have been stripped, but I could find the non-QObject class MetaPoint’s member functions, is it because moc will only strip QObject or inherited classes and ignores non-QObject classes? Anyone knows why? If you know please also provide reference for details.
Q3 Third question, what if I want to provide non-slot-or-signal interfaces for my exported widget class, how should I do this?
Q4 How do I input tab and new line in a post? The preview is ugly, please forgive me.
PS. I know it’s pretty messy and all the damn communists and dictators should all go to hell and got hit by thunder eaten by coyote drawn in the ocean fell down on the mountain bad dreams every night however it would be really appreciated if you could help.
↧
Custom widget plugin design: what's the intuitive approach regarding UI, OO, and widget interfaces?
↧