6. Qt 信号与信号槽(1)

it2023-08-16  74

信号槽是对象和对象之间的通信机制,类似于观察者模式。

object.h

#ifndef DB_OBJECT #define DB_OBJECT #include <map> # define db_slots # define db_signals protected # define db_emit class Object; struct MetaObject{ const char * sig_names; const char * slts_names; static void active(Object * sender, int idx); }; struct Connection{ Object * receiver; int method; }; typedef std::multimap<int, Connection> ConnectionMap; typedef std::multimap<int, Connection>::iterator ConnectionMapIt; class Object{ static MetaObject meta; void metacall(int idx); public: Object(); virtual ~Object(); static void db_connect(Object*, const char*, Object*, const char*); void testSignal(); db_signals: void sig1(); public db_slots: void slot1(); friend class MetaObject; private: ConnectionMap connections; }; #endif #pragma once

object.cpp

#include <stdio.h> #include <string.h> #include "object.h" void MetaObject::active(Object* sender, int idx) { ConnectionMapIt it; std::pair<ConnectionMapIt, ConnectionMapIt> ret; ret = sender->connections.equal_range(idx); for (it = ret.first; it != ret.second; ++it) { Connection c = (*it).second; c.receiver->metacall(c.method); } } static const char sig_names[] = "sig1"; static const char slts_names[] = "slot1"; MetaObject Object::meta = { sig_names, slts_names }; Object::Object() { } Object::~Object() { } static int find_string(const char * str, const char * substr) { if (strlen(str) < strlen(substr)) return -1; int idx = 0; int len = strlen(substr); bool start = true; const char * pos = str; while (*pos) { if (start && !strncmp(pos, substr, len))// && pos[len] == '/n') return idx; start = false; if (*pos == '/n') { idx++; start = true; } pos++; } return -1; } void Object::db_connect(Object* sender, const char* sig, Object* receiver, const char* slt) { int sig_idx = find_string(sender->meta.sig_names, sig); int slt_idx = find_string(receiver->meta.slts_names, slt); if (sig_idx == -1 || slt_idx == -1) { perror("signal or slot not found!"); } else { Connection c = { receiver, slt_idx }; sender->connections.insert(std::pair<int, Connection>(sig_idx, c)); } } void Object::sig1() { MetaObject::active(this, 0); } void Object::metacall(int idx) { switch (idx) { case 0: slot1(); break; default: break; }; } void Object::slot1() { printf("hello dbzhang800!"); } void Object::testSignal() { db_emit sig1(); }

main.cpp

int main(){ Object obj1, obj2; Object::db_connect(&obj1, "sig1", &obj2, "slot1"); obj1.testSignal(); ... }

输出结果为:“hello dbzhang800!”

最新回复(0)