2016-07-06 16 views
2

Ich arbeite derzeit an Anwendung, die in der Tabelle neue Zeile, die in db-Tabelle eingefügt wurde hinzufügen. Ich begann mit Grundklasse meldet Griff und Trigger setted:QT SQL-Benachrichtigung mit Payload

CREATE OR REPLACE FUNCTION notify_tableIWantToObserve_update() 
    RETURNS trigger AS $$ 
DECLARE 
BEGIN 
    PERFORM pg_notify(
     CAST('tableIWantToObserve_update' AS text), 
     (NEW.tableIWantToObserve_id)::text); 
    return new; 
END; 
$$ LANGUAGE plpgsql; 

CREATE TRIGGER tRIGGER_notify_tableIWantToObserve_update 
    AFTER UPDATE 
    ON tableIWantToObserve 
    FOR EACH ROW 
    EXECUTE PROCEDURE notify_tableIWantToObserve_update(); 

So wird es notfy mit der ID von aktualisierten Zeilen in Nutzlast senden jsut. Das ist, was ich will - Becous Nachladen ganzen Tisch wird einfach nicht den Trick später.

I documentaton von QSqlDriver http://doc.qt.io/qt-5/qsqldriver.html#notification-1 geprüft

Damit ich meine "Handler" erstellt:

// Das ist Konstruktor

 MyDB = new QSqlDatabase(QSqlDatabase::addDatabase("QPSQL", "Main")); 

     //Removed my data from here (just fro sake of this post) 
     MyDB->setHostName("-"); 
     MyDB->setPort(0); 
     MyDB->setDatabaseName("-"); 
     MyDB->setUserName("-"); 
     MyDB->setPassword("-"); 

     MyDB->open(); 


    if(MyDB->isOpen()) 
     { 
     qDebug()<<"Connected to DB!"; 
     QObject::connect(
       MyDB->driver(), 
       SIGNAL(notification(const QString&, QSqlDriver::NotificationSource, const QVariant)), 
       this,     
       SLOT(slot_DBNotification_Recieved_NotifiAndPayload((const QString&, const QVariant))); 
       ); 
     } 
     else 
     qDebug()<<"NOT connected to DB!"; 

Aber es jsut nicht funktionieren. Nur wenn das Treibersignal einen einzelnen QString verwendet, wird es verbunden - die Version, die ich benötigte (mit zusätzlichen Informationen), wird nicht verbunden.

Ich habe meine QT auf 5,7 aktualisiert, aber immer noch selbst in QTCreater, zeigt es mir nur, dass das Signal des Treibers nur mit einer einzigen Zeichenfolge ist.

Gibt es eine Lösung dafür? Ich muss wirklich dieses Signal verwenden, um diese aktualisierte Zeilen-ID abzurufen.

EDIT 1:

dass Slot meines Handler:

 void NotifiHandlerr::slot_DBNotification_Recieved_NotifiAndPayload(const QString& MSG, const QVariant &payload) 
     { 
      qDebug() << "I WAS NOTIFIED ABOUT : " + MSG+" WITH DATA : "+payload.toString(); 
     } 

EDIT 2:

Ich versuchte QSqlDriver :: NotificationSource als Argument in meinem Schlitz hinzuzufügen, aber Ich konnte nicht - es wiederholte immer noch Fehler in .h, dass NotificationSource nicht deklariert wurde.

EDIT 3:

Ich füge hier die meisten der Code (Handler-Klasse)

 // WHOLE .h 
     #include <QDebug> 
     #include <QObject> 
     #include <QString> 
     #include <QSqlDatabase> 
     #include <QSqlDriver> 
     #include <QVariant> 
     #include <QSqlDriverPlugin> 
     #include <qsqldriver.h> 


     class Handler : public QObject 
     { 
      Q_OBJECT 
     public slots: 
      void slot_DBNotification_Recieved_NotifiAndPayload 
       (const QString& name, QSqlDriver::NotificationSource source, const QVariant& payload); 

     public: 
      explicit Handler(); 
      ~Handler(); 

     private: 
      QSqlDatabase MyDB; 
     }; 






     //WHOLE .cpp 
     #include "Handler.h" 

     Handler::Handler() 
     { 
     MyDB = new QSqlDatabase(QSqlDatabase::addDatabase("QPSQL", "Main")); 

      MyDB->setHostName("-"); 
      MyDB->setPort(0); 
      MyDB->setDatabaseName("-"); 
      MyDB->setUserName("-"); 
      MyDB->setPassword("-"); 

      MyDB->open(); 


      if(MyDB->isOpen()) 
      { 
      qDebug()<<"Connected to DB!"; 
      MyDB->driver()->subscribeToNotification("tableIWantToObserve_update"); 
      QObject::connect(
       MyDB->driver(), 
       SIGNAL(notification(const QString&, QSqlDriver::NotificationSource, const QVariant)), 
       this,     
       SLOT(slot_DBNotification_Recieved_NotifiAndPayload((const QString&, const QVariant))); 
       ); 
      } 
      else 
      qDebug()<<"NOT connected to DB!"; 
     } 

     Handler::~Handler() 
     { 
       MyDB->driver()->unsubscribeFromNotification("tableIWantToObserve_update"); 
    MyDB->cloe(); 
     } 

     void NotificationMaster::slot_DBNotification_Recieved_NotifiAndPayload 
     (const QString &name, QSqlDriver::NotificationSource source, const QVariant &payload) 
     { 
      qDebug() << "I WAS NOTIFIED ABOUT : " + name+" WITH DATA : "+payload.toString(); 
     } 

Und genau diese Idee zu beseitigen - ich

hinzugefügt
  QT += sql 

in meine .pro Datei

Antwort

0

-Code von mir und in anserw geschrieben waren mehr oder weniger richtig, aber was getan werden muß, ist whoel Projekt in neuerer Version von Qt Creator zu erstellen, so dass es issiues lösen wird mit fehlenden Funktionen und Namespaces. Erstellen Sie einfach ein neues Projekt und fügen Sie alle Dateien dort ein.

0

Ihr Steckplatz hat eine falsche Signatur, Her e ist, wie Sie es definieren sollten.

In Ihrem Header-Datei:

//in order to be able to use the enum QSqlDriver::NotificationSource 
#include <QSqlDriver> 
... 
... 

class Handler : public QObject{ 
    Q_OBJECT 
public: 
    explicit Handler(QObject *parent = 0); 
    ~Handler(); 
    ... 
    ... 
    ... 
public slots: 
    void SqlNotification(const QString& name, QSqlDriver::NotificationSource source, 
         const QVariant& payload); 
    ... 
    ... 
}; 

und im Konstruktor, wenn Sie den Steckplatz anschließen, sollten Sie zunächst auf die Benachrichtigung abonnieren:

QSqlDatabase::database().driver()->subscribeToNotification("notification_name"); 
connect(QSqlDatabase::database().driver(), 
     SIGNAL(notification(QString,QSqlDriver::NotificationSource,QVariant)), this, 
     SLOT(SqlNotification(QString,QSqlDriver::NotificationSource,QVariant))); 

Sie können in der austragen müssen Destruktor (da Sie die Benachrichtigung nicht mehr erhalten möchten):

QSqlDatabase::database().driver()->unsubscribeFromNotification("notification_name"); 

und Ihre Slot Implementierung:

void Handler::SqlNotification(const QString &name, QSqlDriver::NotificationSource source, const QVariant &payload){ 
    switch(source){ 
    case QSqlDriver::UnknownSource: 
     qDebug() << "unkown source, name: " << name << "payload:" << payload.toString(); 
     break; 
    case QSqlDriver::SelfSource: 
     qDebug() << "self source, name: " << name << "payload:" << payload.toString(); 
     break; 
    case QSqlDriver::OtherSource: 
     qDebug() << "other source, name: " << name << "payload:" << payload.toString(); 
     break; 
    } 
} 
+0

Aa erwähnt I (@Edit 2) - Ich bin Fehler immer \t Fehler: 'QSqlDriver :: NotificationSource' wenn ich verwenden NotificationSource versuchen wurde nicht erklärt. Ich implementierte auch meinen Code Liek dies für die erste Zeit - ich bekam immer noch einen Fehler und immer noch sah es aus wie Treiber bekam nur Steckplatz mit einzelnen String. – Arker

+0

stellen Sie sicher, dass Sie # 'in Ihre' .h' Datei einfügen, wie ich es in meiner Antwort geschrieben habe – Mike

+0

Es war. Ich dachte seine "grundlegende" Sache, also habe ich diesen Teil des Codes hier nicht eingeschlossen. – Arker