PDA

View Full Version : QModelIndex problem!



landonmkelsey
22nd August 2008, 07:01
I incorporated the following example's methods into my code!


#include <QtCore>
#include <QtGui>

class Inserter : public QObject {
public:
Inserter(QStandardItemModel *m) : QObject() {
model = m;
}
protected:
void timerEvent(QTimerEvent *e){
QString str = QDateTime::currentDateTime().toString();
model->appendRow(new QStandardItem(str));
}
private:
QStandardItemModel *model;
};

int main(int argc, char **argv){
QApplication app(argc, argv);
QStandardItemModel model;
model.setColumnCount(1);
QListView lv;
lv.setModel(&model);
lv.show();
Inserter ins(&model);
ins.startTimer(1000);
return app.exec();
}


The entries show up OK whilst in the vicinity of the starting code!

However off in a thread I am doing the same code:



QString qstr("landon 2nd");

model->appendRow(new QStandardItem(qstr));


However, I get the following errors at run time and no entry:



QObject::connect: Cannot queue arguments of type 'QModelIndex'
(Make sure 'QModelIndex' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QModelIndex'
(Make sure 'QModelIndex' is registered using qRegisterMetaType().)


Somehow the thread is not connected to the QModelIndex used at the beginning :confused:

I am feverishly researching the matter whilst reading about MVC.

qRegisterMetaType<QString>(); --->>>didn't work!

jacek
22nd August 2008, 09:52
You shouldn't touch the GUI in a non-GUI thread. You have to access your model through a queued connection, not directly.

landonmkelsey
22nd August 2008, 19:15
Thanks!

Therefore, the following counts as a "gui thread" since it works!




void timerEvent(QTimerEvent *e){
QString str = QDateTime::currentDateTime().toString();
model->appendRow(new QStandardItem(str));
}

If the class inherits from QObject, maybe that "counts"

Knowing full well, this probably wouldn't work, I programmed a facility for the thread to call a function back in the model's home turf.


void tcpip::addQString(QString qstr)
{
model->appendRow(new QStandardItem(qstr));
QApplication::processEvents();
}


It didn't work! I'm going to have to thinks some more!

I could put the strings in a list accessible to everybody and have still another thread update the model! But there it is again!

This is like the concept of remote object invocation where no environment is involved!

May have changed but .NET windows services cannot interact with windows-guis.

A gui windows program CAN observe information produced by the Windows service!...HMMMM!

jacek
23rd August 2008, 15:54
If the class inherits from QObject, maybe that "counts"
No, it doesn't matter from what class it was derived. The important thing is where the object was created, as objects belong to the thread in which they were created (of course you can later move them between threads).


Knowing full well, this probably wouldn't work, I programmed a facility for the thread to call a function back in the model's home turf.
Let's start from the beginning. Why do you need a thread?

landonmkelsey
23rd August 2008, 19:46
I have 2 threads now

(1) a thread that leavess the main mechanism of the program in its own thread so events can take place in the new QThread thread. We solved this problem in another thread last week. At that time I was doing non-model posts to a QListWidget. I am now getting "stuff" in the QListWidget(I've learned doesn't do MVC)

(2) one model of tcpip/tcp requires (as a concurrent server) a thread to handle each client that "calls" in!

Each thread handles each client. Prior to Qt 4 I was using a Posix thread that has worked flawlessly for years! I scrapped the Posix thread and am now using QThread everywhere!

In any case, I am learning a lot. I like the MVC and am also reading along with practice!

Thanks for your patience!

Remember the MVC example you sent??? Well I incorporated it into my tcpip startup to see if at least it would generate some display! It hasn't yet!



class Inserter : public QObject {
public:
Inserter(QStandardItemModel *m) : QObject() {
model = m;
}
protected:
void timerEvent(QTimerEvent *e){
QString str = QDateTime::currentDateTime().toString();
model->appendRow(new QStandardItem(str));
}
private:
QStandardItemModel *model;
};



Timer thing didn't work either:


void tcpip::StartTCPServer()
{
ui.listWidgetServer->addItem(QString("server1 StartTCPServer"));

ui.listViewServer->setModel(model);
model->setColumnCount(1);
QString str("landon is first");
model->appendRow(new QStandardItem(str));

QString str2("landon is second");
model->appendRow(new QStandardItem(str2));
QApplication::processEvents();
bool ok = true;
QString qstr = ui.lineEditTCPIPServerPortServer->text();
port = qstr.toInt(&ok);
//qDebug()<<" server port "<<port;
ui.lineEditServerStatus->setText("server started");

QApplication::processEvents();

tcpipThread* ptcpipThreadStart = new tcpipThread(ui, port, this);
ptcpipThreadStart->start();

Inserter ins(model);
ins.startTimer(1000);


}




class Inserter : public QObject {
public:
Inserter(QStandardItemModel *m) : QObject() {
model = m;
}
protected:
void timerEvent(QTimerEvent *e){
QString str("hello");
model->appendRow(new QStandardItem(str));
qDebug()<<"hello";
}
private:
QStandardItemModel *model;
};

wysota
25th August 2008, 07:28
I suggest redesigning the original code. Starting one thread per client is a doubtful solution. For 100 clients you'll have 101 threads... That's quite a stress on the system - context switching will kill you when the number of clients increases.

landonmkelsey
25th August 2008, 19:35
The point here is to learn something!

If I had surrendered/redesigned every time I ran into a problem, I'd never have learned anything!

The code is unimportant here since my ultimate aim is to incorporate the bridge pattern. Ultimately the user will be able to choose the means of server concurrency
via the bridge pattern. In C# this is straightforward!

My code in C# is a great testament to the value of patterns!

Redesign? Why? The user chooses ultimately!

I started out trying to incorporate Qt4 for gui into my already running program!

The means of concurrency in TCP/IP is controversial anyway!

See great work of the deceased W Richard Stevens! www.kohala.com

wysota
25th August 2008, 23:19
The point here is to learn something!

If I had surrendered/redesigned every time I ran into a problem, I'd never have learned anything!
You would learn to avoid bad designs and create good ones.


Redesign? Why? The user chooses ultimately!
Because the solution is neither scalable nor modular nor straightforward.


I started out trying to incorporate Qt4 for gui into my already running program!
So what's keeping you from rewriting some parts of the application to simplify the overall solution instead of wrestling against problems related to mixing two different technologies that only need a minor change to interoperate perfectly?


The means of concurrency in TCP/IP is controversial anyway!

I'm not sure what you mean here, but there are numerous designs related to obtaining concurrency in TCP connections - just look at available operation modes of the Apache webserver. If you want multithreading, you are welcome to use it but do it properly, for example by using a thread pool to keep resource usage at a reasonable level while keeping your system responsive.

landonmkelsey
28th August 2008, 19:49
the main point is !

My C# code uses a bridge pattern to allow the user programmer to select which "client handler" he/she wants/supplies! One can choose the thread pool or 1 client one thread generated on "call-in"

One may even choose an iterative server!

I wanted to generate C++ code to do the same thing! Since C++ does not have an "interface", I would have to use an ABC!

I'll solve the problem myself! Thanks for your help!:)

I quess C++ will wither and die! : ( as Java and VB)

done!

jacek
28th August 2008, 20:18
Since C++ does not have an "interface", I would have to use an ABC!
You don't need a separate keyword for everything. An interface is a special kind of ABC.

wysota
28th August 2008, 20:46
My C# code uses a bridge pattern to allow the user programmer to select which "client handler" he/she wants/supplies! One can choose the thread pool or 1 client one thread generated on "call-in"


I quess C++ will wither and die! : ( as Java and VB)

The language used is independent of the design. If you have some design in C#, you can implement the same design in other languages.

On the other hand a bad design is bad independent of the language used to implement it.

You are trying to bridge two technologies that use different concepts. This is possible but prone to errors and that's exactly what you are experiencing. So you can either struggle with that or change one of the concepts.

As for interfaces - interface is an abstract term. Each class is an interface, a class containing virtual methods is an interface that can be realized in different ways by more than one class, a class containing pure abstract methods is an abstract interface that has to be implemented by other class(es) (an ABC).