PDA

View Full Version : QThread and QDataTable



ederbs
10th October 2006, 23:33
I have one Form1 that it needs update immediate, when somebody I inserted some data in the DB automatically this data must appear in the Form1 of the user.

For this I am using the events NOTIFY / LISTEN of PostgreSQL and QThreads.

More I am having difficulties to give refresh in the screen.

they observe the code.


/////////////// thread.h ///////////////////////////////
#ifndef THREAD_H
#define THREAD_H

#include <qthread.h>

class Thread : public QThread
{
public:
Thread();

virtual void backSqlThreadStart();

virtual void run();
virtual void stop();

private:
volatile bool stopped;
};
#endif
------------------------------------------------------------------------------


/////////////// thread.cpp ///////////////////////////////
extern "C" {
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include "libpq-fe.h"
}

#include "thread.h"

Thread::Thread()
{
stopped = false;
}

static void exit_nicely(PGconn *conn)
{
PQfinish(conn);
}

void Thread::backSqlThreadStart()
{
const char *conninfo;
PGconn *conn;
PGresult *res;
PGnotify *notify;
int nnotifies;

conninfo = "dbname = developers";

/* Make a connection to the database */
conn = PQconnectdb(conninfo);

/* Check to see that the backend connection was successfully made */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database '%s' failed.\n", PQdb(conn));
fprintf(stderr, "%s", PQerrorMessage(conn));
exit_nicely(conn);
}

/*
* Issue LISTEN command to enable notifications from the rule's NOTIFY.
*/
res = PQexec(conn, "LISTEN TBL2");
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "LISTEN command failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}

/*
* should PQclear PGresult whenever it is no longer needed to avoid
* memory leaks
*/
PQclear(res);

/* Quit after four notifies are received. */
nnotifies = 0;
while (nnotifies < 200)
{
/*
* Sleep until something happens on the connection. We use select(2)
* to wait for input, but you could also use poll() or similar
* facilities.
*/
int sock;
fd_set input_mask;

sock = PQsocket(conn);

if (sock < 0)
break; /* shouldn't happen */

FD_ZERO(&input_mask);
FD_SET(sock, &input_mask);

if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0)
{
fprintf(stderr, "select() failed: %s\n", strerror(errno));
exit_nicely(conn);
}

/* Now check for input */
PQconsumeInput(conn);
while ((notify = PQnotifies(conn)) != NULL)
{
fprintf(stderr,
"ASYNC NOTIFY of server FNS2 '%s' received from backend pid %d\n",
notify->relname, notify->be_pid);
PQfreemem(notify);
nnotifies++;
}
}

fprintf(stderr, "Done.\n");

/* close the connection to the database and cleanup */
PQfinish(conn);

return true;
}

void Thread::run()
{
while (!stopped)
backSqlThreadStart();
stopped = false;

}

void Thread::stop()
{
stopped = true;
}
-------------------------------------------------------------------------------

In form1 I invoke thread, and the notifications appear in the console, the problem are to bring update the QDataTable of the Form1.

As I inside make of my QThread archive to bring up to date the QDataTable of the Form1 is accurately in this part of the code.


///////////////////// thread.cpp //////////////////////////////
/* Now check for input */
PQconsumeInput(conn);
while ((notify = PQnotifies(conn)) != NULL)
{
/* some thing of the type */
//Parent->dataTable->refresh();

fprintf(stderr,
"ASYNC NOTIFY of server FNS2 '%s' received from backend pid %d\n",
notify->relname, notify->be_pid);
PQfreemem(notify);
nnotifies++;
}
}
-----------------------------------------------------------------

They forgive for the bad English,

Ederson.

Update! Added code tags.

e8johan
11th October 2006, 08:22
How come you are using PQ directly instead of through the QtSql module?

The obvious way to do what you want to do is to emit a signal to the dialog in question as soon as a change takes place.