2016-07-06 2 views
2

В настоящее время я работаю над applciation, который добавит в таблицу новую строку, которая была вставлена ​​в таблицу db. Я начал с базовым классом для обработки и извещает выставиться спусковыми:Уведомление QT SQL с полезной нагрузкой

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(); 

Так это будет как раз пошлите notfy с идентификатором обновленной строки в полезной нагрузке. Это то, что я хочу, - потому что перезагрузка всего стола просто не поможет.

Я проверил documentaton из QSqlDriver http://doc.qt.io/qt-5/qsqldriver.html#notification-1

С этим, я создал свой "обработчик":

// Это его конструктор

 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!"; 

Но этого нужно просто не будет работать. Только с сигналом водителя, использующим один QString, он подключится к нему - мне нужна версия (с дополнительной информацией), которая не будет подключаться.

Я обновил свой QT до 5.7, но все же даже в QTCreater, это просто показывает мне, что сигнал драйвера только с одной строкой.

Есть ли какое-либо исправление для этого? Я действительно должен использовать этот сигнал для получения обновленного идентификатора строки.

EDIT 1:

, что слот моего обработчика:

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

EDIT 2:

Я пытался добавить QSqlDriver :: NotificationSource в качестве аргумента в моем слоте, но я не мог - он все еще повторял ошибку в .h, что NotificationSource не был объявлен.

EDIT 3:

Я добавляю здесь большую часть кода (класс обработчика)

 // 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(); 
     } 

И просто устранить эту идею - я добавил

  QT += sql 

в мой .pro файл

ответ

0

код отправленный мной и в anserw были более или менее правильно, но то, что нужно сделать, это восстановить whoel проект в новой версии Qt Creator, так что разрешит issiues с отсутствующими функциями и пространствами имен. Просто создайте новый проект и вставьте туда все файлы.

0

У вашего слота неправильная подпись, Ее e, как вы должны это определить.

В файле заголовка:

//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); 
    ... 
    ... 
}; 

и в конструкторе, когда вы подключаете слот, вы должны подписаться на уведомления первого:

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

Вы, возможно, потребуется отменить подписку в деструктор (так как вы не хотите получать уведомление больше):

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

и ваша реализация слот:

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

Аа я упомянул (@Edit 2) - я получаю ошибку \t ошибка: 'QSqlDriver :: NotificationSource' не был объявлен всякий раз, когда я пытаюсь использовать NotificationSource. Я также реализовал свой код liek для этого времени - я все еще получал сообщение об ошибке, и все же он выглядел так, что у водителя был только слот с одной строкой. – Arker

+0

убедитесь, что '#include ' в вашем '.h' файле, как я написал в своем ответе – Mike

+0

Это было. Я думал, что это «основная» вещь, поэтому я не включил эту часть кода здесь. – Arker

Смежные вопросы