Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 2

Qt-interest Archive, July 2007
Help needed with synchronising views


Message 1 in thread

Hi,

 

I'm using the Model/View architecture in Qt 4.2.  I have a table displaying
data from a model.

 

In the driver program (a QDialog), I'm doing a lot of work, among other
things updating the model.  I want this to an immediate update of the view
(a separate, unparented widget), but I can't get this to happen.

 

I've tried a few things to get this to work:

1.	Displaying a QMessageBox when I update the model forces the view to
be updated.  So I suspect the view is just not getting any process time to
do its update.
2.	Given the above, I tried butting the view in a new QThread, hoping
that it would then get refreshed more regularly.  This did not work either.
I put a breakpoint in the run() method (which is basically a while (1)
{msleep (50);}) and this is regularly getting called.  But I can't work out
how to force a redraw from in here.

 

Any suggestions would be greatly appreciated.

 

Thanks.

 

Darryl

 


Message 2 in thread

On 07.07.07 17:03:20, Darryl Hunter wrote:
> I'm using the Model/View architecture in Qt 4.2.  I have a table displaying
> data from a model.
> 
> In the driver program (a QDialog), I'm doing a lot of work, among other
> things updating the model.  I want this to an immediate update of the view
> (a separate, unparented widget), but I can't get this to happen.

You should put the workload into a separate thread and either use queued
signal/slots to communicate the results to the model or use custom
event's to do that.

Andreas

-- 
 [ signature omitted ] 

Message 3 in thread

I've moved a simple text editor from Qt3 to Qt4. Initially using 
Q3TextEdit all worked
fine, however when trying to replace that with a native QTextEdit I have 
run into a
couple of problems:

- I can't seem to set text colour.  If I do the following to append to 
the end of the QTextEdit

  m_TextEdit->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
  QTextCursor cursor = m_TextEdit->textCursor();
  m_TextEdit->setTextColor(m_TextColor);
  cursor.insertText(str);

then the text gets inserted OK, but the text remains in black. Is this 
the correct
way to use setTextColor()?

- I can't resize the QTextEdit. It's the only widget in a QDockWidget, 
yet if
I try and resize either the dock widget itself or the QTextEdit, nothing 
happens.
If I set a maximum or minimum height, that is obeyed. Using resize() on the
QDockWidget worked when it contained a Q3TextEdit. Is this a bug?

thanks,

Keith

--
 [ signature omitted ] 

Message 4 in thread

On 7/7/07, Andreas Pakulat <apaku@xxxxxx> wrote:
> On 07.07.07 17:03:20, Darryl Hunter wrote:
> > I'm using the Model/View architecture in Qt 4.2.  I have a table
> displaying
> > data from a model.
> >
> > In the driver program (a QDialog), I'm doing a lot of work, among other
> > things updating the model.  I want this to an immediate update of the view
> > (a separate, unparented widget), but I can't get this to happen.
>
> You should put the workload into a separate thread and either use queued
> signal/slots to communicate the results to the model or use custom
> event's to do that.
>
> Andreas
>
> --
> Blow it out your ear.
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>

--
 [ signature omitted ] 

Message 5 in thread

Thanks for your advice.

I've now created a QThread-derived class that does the processing.  I have a
signal in that, which is emitted when the model needs to get updated.  The
model is NOT in a thread (but in the main event loop).  I put a breakpoint
in the slot, but still, that's only getting called when the thread finishes
its processing.

Any other suggestions?  I've probably just missed something silly so any
advice would be appreciated.

Thanks again.

Darryl


-----Original Message-----
From: Andreas Pakulat [mailto:apaku@xxxxxx] 
Sent: Saturday, 7 July 2007 5:32 PM
To: qt-interest@xxxxxxxxxxxxx
Subject: Re: Help needed with synchronising views

On 07.07.07 17:03:20, Darryl Hunter wrote:
> I'm using the Model/View architecture in Qt 4.2.  I have a table
displaying
> data from a model.
> 
> In the driver program (a QDialog), I'm doing a lot of work, among other
> things updating the model.  I want this to an immediate update of the view
> (a separate, unparented widget), but I can't get this to happen.

You should put the workload into a separate thread and either use queued
signal/slots to communicate the results to the model or use custom
event's to do that.

Andreas

-- 
 [ signature omitted ] 

Message 6 in thread

On 09.07.07 19:04:18, Darryl Hunter wrote:
> I've now created a QThread-derived class that does the processing.  I have a
> signal in that, which is emitted when the model needs to get updated.  The
> model is NOT in a thread (but in the main event loop).  I put a breakpoint
> in the slot, but still, that's only getting called when the thread finishes
> its processing.
> 
> Any other suggestions?  I've probably just missed something silly so any
> advice would be appreciated.

Without some example code its really hard to tell why your slot is
called after the thread is finished.

Andreas

-- 
 [ signature omitted ] 

Message 7 in thread

I've put together a simple program to illustrate what I'm getting... I don't
like posting large files, so I've cut this down as much as I can.

--------------------
MyWidget.h
#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QMainWindow.h>
#include <qlabel.h>
#include <qpushbutton.h>

class MyWidget : public QMainWindow
{
    Q_OBJECT

public:
    MyWidget(QWidget *parent = 0);

private slots:
    void on_pb_clicked();
	void doUpdate();

protected:
	int number;
	QLabel *label;
	QPushButton *pb;
};

#endif

--------------------
MyWidget.cpp:
#include <QtGui>

#include "mywidget.h"

#include "WorkClass.h"

MyWidget::MyWidget(QWidget *parent)
    : QMainWindow(parent)
{
	QWidget *window = new QWidget;
	setCentralWidget (window);

	label=new QLabel ("Not Set");
	pb=new QPushButton ("Go");

	QHBoxLayout *layout = new QHBoxLayout;
	layout->addWidget(label);
	layout->addWidget(pb);

	window->setLayout(layout);
	window->show();

	connect (pb, SIGNAL (clicked()), SLOT (on_pb_clicked()));
	number=0;
	show();
}

void MyWidget::on_pb_clicked()
{
	WorkClass wc;
	connect (&wc, SIGNAL (workProcessed()), this, SLOT (doUpdate()));

	wc.start();
	wc.wait();
}

void MyWidget::doUpdate()
{
	number++;
	label->setText (QString::number (number));
}

--------------------
WorkClass.h:
#if !defined(WORKCLASS_H)
#define WORKCLASS_H

#include <qthread.h>

class WorkClass : public QThread  
{
	Q_OBJECT
public:
	WorkClass(){};
	virtual ~WorkClass(){};

protected:
	void run();

signals:
	void workProcessed();
};

#endif // WORKCLASS_H

--------------------
WorkClass.cpp:
#include "WorkClass.h"

void WorkClass::run()
{
	qDebug ("Processing...");

	for (int i=0; i<3; i++)
	{
		sleep (1);
		emit (workProcessed());
	}
}

--------------------
Main.cpp:
#include <QApplication>

#include "mywidget.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MyWidget widget;
    widget.show();
    return app.exec();
}

If you run this, and press the button that appears, then wait 3 seconds and
the label will be set to 3.  What *should* happen is that the label gets
updated to 1, 2 and then 3 (with a 1 second delay).

Darryl

-----Original Message-----
From: Andreas Pakulat [mailto:apaku@xxxxxx] 
Sent: Monday, 9 July 2007 7:36 PM
To: qt-interest@xxxxxxxxxxxxx
Subject: Re: Help needed with synchronising views

On 09.07.07 19:04:18, Darryl Hunter wrote:
> I've now created a QThread-derived class that does the processing.  I have
a
> signal in that, which is emitted when the model needs to get updated.  The
> model is NOT in a thread (but in the main event loop).  I put a breakpoint
> in the slot, but still, that's only getting called when the thread
finishes
> its processing.
> 
> Any other suggestions?  I've probably just missed something silly so any
> advice would be appreciated.

Without some example code its really hard to tell why your slot is
called after the thread is finished.

Andreas

-- 
 [ signature omitted ] 

Message 8 in thread

On 09.07.07 20:09:36, Darryl Hunter wrote:
> I've put together a simple program to illustrate what I'm getting... I don't
> like posting large files, so I've cut this down as much as I can.

Good.

> --------------------
> MyWidget.h
> #ifndef MYWIDGET_H
> #define MYWIDGET_H
> 
> #include <QMainWindow.h>

You're working on win32 right? I suggest to use either lowercase+.h or
mixed case without the .h, else your application is not portable to
Systems that have case-sensitive filesystems.

> void MyWidget::on_pb_clicked()
> {
> 	WorkClass wc;
> 	connect (&wc, SIGNAL (workProcessed()), this, SLOT (doUpdate()));
> 
> 	wc.start();
> 	wc.wait();
> }

> If you run this, and press the button that appears, then wait 3 seconds and
> the label will be set to 3.  What *should* happen is that the label gets
> updated to 1, 2 and then 3 (with a 1 second delay).

Of course, because after the thread is started you wait until its
finished. So the events that are created for the signals
(cross-thread-signals are implemented using events and the event queue)
are only delivered after the thread is finished. If you remove the wait
and make sure the thread lives long enough (i.e. make it a pointer or
member of the widget class) it works as you want it.

Andreas

-- 
 [ signature omitted ] 

Message 9 in thread

Thanks for the help Andreas.  I knew it would be something silly.  That
works in the example I sent, but not completely in my application.  There
were a couple of subtle differences, such as the example wasn't using the
model/view approach.  I eventually found that, by subclassing
QStandardItemModel and giving it a slot to do the update, and then emitting
a signal to trigger the update, it worked.  But by passing a reference to a
QStandardItemModel and updating it directly from within the QThread-derived
class, this did NOT do the update (unless a refresh was triggered by moving
something around the screen).  Strange, but (finally) my problem is solved.

Thanks for the "portable coding tip" too - I've only just started using Qt 4
(been on Qt 3 for a few years where it's all lower case with .h).  I
overlooked the extension not being on the mixed case names.  I'll keep that
in mind (as I do try to write portable code).

Darryl

-----Original Message-----
From: Andreas Pakulat [mailto:apaku@xxxxxx] 
Sent: Wednesday, 11 July 2007 6:33 AM
To: qt-interest@xxxxxxxxxxxxx
Subject: Re: Help needed with synchronising views

On 09.07.07 20:09:36, Darryl Hunter wrote:
> I've put together a simple program to illustrate what I'm getting... I
don't
> like posting large files, so I've cut this down as much as I can.

Good.

> --------------------
> MyWidget.h
> #ifndef MYWIDGET_H
> #define MYWIDGET_H
> 
> #include <QMainWindow.h>

You're working on win32 right? I suggest to use either lowercase+.h or
mixed case without the .h, else your application is not portable to
Systems that have case-sensitive filesystems.

> void MyWidget::on_pb_clicked()
> {
> 	WorkClass wc;
> 	connect (&wc, SIGNAL (workProcessed()), this, SLOT (doUpdate()));
> 
> 	wc.start();
> 	wc.wait();
> }

> If you run this, and press the button that appears, then wait 3 seconds
and
> the label will be set to 3.  What *should* happen is that the label gets
> updated to 1, 2 and then 3 (with a 1 second delay).

Of course, because after the thread is started you wait until its
finished. So the events that are created for the signals
(cross-thread-signals are implemented using events and the event queue)
are only delivered after the thread is finished. If you remove the wait
and make sure the thread lives long enough (i.e. make it a pointer or
member of the widget class) it works as you want it.

Andreas

-- 
 [ signature omitted ]