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

Qt-interest Archive, January 2008
SIGNALS and SLOTS using custom classes

Pages: Prev | 1 | 2 | 3 | Next

Message 1 in thread

Qt!

The docs say that every class that implements a 

* public constructor
* public copy constructor
* public destructor

can be registered using qRegisterMetaType and be used in SIGNALS and SLOTS.

This works well when emiting the SIGNALS to objects that are created in the
same thread. But, a strange behavior occurs when emiting them to objects in
other threads. The receiver slot gets never called. 

Maybe the custom class does not meet the requierements for the queued
connections??

The event loop of the receiver object is entered. I can figure this out
because in my case the receiving object lifes in the main thread (gui
thread) and after emiting the signal (from a different thread) the gui does
not respond on user interactions anymore.

This is the custom class used in SIGNALS/SLOTS:

class Data
{
public:
        Data() {}
        ~Data() {}
        Data( const Data & d ) {
                qDebug() << "Data:Data copy constructor" << this;
                copyMetaData(d);
                data = d.data;
        }
        
        void copyMetaData( const Data & d ) {
                dummy = d.dummy;
                mtotal = d.mtotal;
                ptotal = d.ptotal;
                props = d.props;
                pstartpixel = d.pstartpixel;
                pcount = d.pcount;
                msize = d.msize;
                mstartpixel = d.mstartpixel;
                totalsize = d.totalsize;
        }
        
        bool dummy;
        int mtotal;      // mosaic
        int ptotal;      // part
        QByteArray data;
        P props;
        QPoint pstartpixel,pcount;
        QPoint msize,mstartpixel;
        QPoint totalsize;
};


Any ideas??

Frank


--
 [ signature omitted ] 

Message 2 in thread

On Sun, Jan 20, 2008 at 01:15:10PM +0100, Frank wrote:
> Qt!
> 
> The docs say that every class that implements a 
> 
> * public constructor
> * public copy constructor
> * public destructor
> 
> can be registered using qRegisterMetaType and be used in SIGNALS and SLOTS.
> 
> This works well when emiting the SIGNALS to objects that are created in the
> same thread. But, a strange behavior occurs when emiting them to objects in
> other threads. The receiver slot gets never called. 
> 
> Maybe the custom class does not meet the requierements for the queued
> connections??
> 

Queued connections works here with custom classes. Look to stderr of your
app. QObject::connect() will report problems.

Also try to create as little as possible test example.

-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: Digital signature


Message 3 in thread

Hi Dmitry!


Dmitry Nezhevenko wrote:

> On Sun, Jan 20, 2008 at 01:15:10PM +0100, Frank wrote:
>> Qt!
>> 
>> The docs say that every class that implements a
>> 
>> * public constructor
>> * public copy constructor
>> * public destructor
>> 
>> can be registered using qRegisterMetaType and be used in SIGNALS and
>> SLOTS.
>> 
>> This works well when emiting the SIGNALS to objects that are created in
>> the same thread. But, a strange behavior occurs when emiting them to
>> objects in other threads. The receiver slot gets never called.
>> 
>> Maybe the custom class does not meet the requierements for the queued
>> connections??
>> 
> 
> Queued connections works here with custom classes. Look to stderr of your
> app. QObject::connect() will report problems.
> 

There are no problems reported. I double checked by slightly renaming the
SLOT, then it reports problems at runtime. So this is not the problem.

Any other suggestions?

Frank

--
 [ signature omitted ] 

Message 4 in thread

When I change the class to be a struct it works.

What is the basic difference when using a struct or a class in SIGNALS ???



struct Data
{
        bool dummy;
        int mtotal;      // mosaic
        int ptotal;      // part
        QByteArray data;
        P props;
        QPoint pstartpixel,pcount;
        QPoint msize,mstartpixel;
        QPoint totalsize;
};


Original class:

class Data
{
public:
        Data() {}
        ~Data() {}
        Data( const Data & d ) {
                qDebug() << "Data:Data copy constructor" << this;
                copyMetaData(d);
                data = d.data;
        }
        
        void copyMetaData( const Data & d ) {
                dummy = d.dummy;
                mtotal = d.mtotal;
                ptotal = d.ptotal;
                props = d.props;
                pstartpixel = d.pstartpixel;
                pcount = d.pcount;
                msize = d.msize;
                mstartpixel = d.mstartpixel;
                totalsize = d.totalsize;
        }
        
        bool dummy;
        int mtotal;      // mosaic
        int ptotal;      // part
        QByteArray data;
        P props;
        QPoint pstartpixel,pcount;
        QPoint msize,mstartpixel;
        QPoint totalsize;
};


Frank

--
 [ signature omitted ] 

Message 5 in thread

Hi,

> When I change the class to be a struct it works.

Strange, it could be a bug then. Could you provide a minimal, compilable 
example that reproduces the problem?

--
 [ signature omitted ] 

Message 6 in thread

Hi Dimitri!

I tried to compile a minimum example. But, the software is in very minimal
state. It contains just the motor and some GUI to use it. So compiling a
more minimum example of it is hard.

I packed a tgz of the software and uploaded it to my web space at

www.ifh.de/~fwinter/mini.tgz

To compile and run do a

cd mini
qmake -r
make
bin_debug/amatel_debug

This version contains "Data" implemented as a struct and works fine. The
receiver (mainwindow) slot is being called indicated by the last line of
debug output "Debug: MainWindow::inData 0..15". The receiver slot is
located in file src/app/mainwindow.cpp

If you change the "Data" struct into a class by commenting out in file
src/app/queue.h the struct Data and uncommenting the class Data that
rightly follows and do a make and run the application again you can see
that the receiver slot is no more called. But there was no problem ever
reported with QObject::connect at runtime.

Executions hangs right after emiting the signal from Gemi::inData(Data in)
in src/bp/gemi/gemi.cpp to the mainwindow. In the struct version this
works.

Frank



Dimitri wrote:

> Hi,
> 
>> When I change the class to be a struct it works.
> 
> Strange, it could be a bug then. Could you provide a minimal, compilable
> example that reproduces the problem?
> 
> --
> Dimitri

--
 [ signature omitted ] 

Message 7 in thread

Hi,

> I tried to compile a minimum example. But, the software is in very minimal
> state. It contains just the motor and some GUI to use it. So compiling a
> more minimum example of it is hard.

It shouldn't be that, try keepign less than 50 lines that are directly related 
to the problem. Discard images, the GUI, etc.

--
 [ signature omitted ] 

Message 8 in thread

Dimitri!

I am sorry for the last long version. I was afraid not to reproduce the
error without the facilities I use (Plugins, Factories). But it can be
reproduced without Plugins and Factories.

When using a "class" in the SIGNAL the receiver SLOT does not get called
when emitting the SIGNAL from insider the WorkerThread. When using
a "struct" it gets called.

I compiled the most minimal code that occured to me from scratch:

www.ifh.de/~fwinter/test.tgz

cd test
qmake
make
./app

In this version the "class" is used, i.e. the receiver slot is not being
called. Comment out the class and uncomment the struct in file "data.h" and
make the project again. Then it works.

make
./app


Frank




Dimitri wrote:

> Hi,
> 
>> I tried to compile a minimum example. But, the software is in very
>> minimal state. It contains just the motor and some GUI to use it. So
>> compiling a more minimum example of it is hard.
> 
> It shouldn't be that, try keepign less than 50 lines that are directly
> related to the problem. Discard images, the GUI, etc.
> 
> --
> Dimitri

--
 [ signature omitted ] 

Message 9 in thread

Hi there

Is there anyone who knows ho to stop a treenode from being selected with the 
mouse? I need to stay on the current node if some validation fails. 
Although I can install an eventfilter on the QTreeWidget that catches keyUp, 
KeyDown etc, this does not seem to work for the mouse.
If I trace the eventype with qDebug, I never see the mouse events pass and 
even if I install the eventfilter on the dialog itself, it only shows 
mouseevents when I click on the dialog itself, not when I click on the 
TreeWidget.

Does anyone have a clue?

Happy coding,
Eric

--
 [ signature omitted ] 

Message 10 in thread

On Sun, Jan 20, 2008 at 11:48:43PM +0100, Eric Methorst wrote:
> Hi there
> 
> Is there anyone who knows ho to stop a treenode from being selected with the 
> mouse? I need to stay on the current node if some validation fails. 
> Although I can install an eventfilter on the QTreeWidget that catches keyUp, 
> KeyDown etc, this does not seem to work for the mouse.
> If I trace the eventype with qDebug, I never see the mouse events pass and 
> even if I install the eventfilter on the dialog itself, it only shows 
> mouseevents when I click on the dialog itself, not when I click on the 
> TreeWidget.
> 

Try to use QTreeWidgetItem::setFlags()

-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: Digital signature


Message 11 in thread

On Monday 21 January 2008 06:26:09 Dmitry Nezhevenko wrote:
> On Sun, Jan 20, 2008 at 11:48:43PM +0100, Eric Methorst wrote:
> > Hi there
> >
> > Is there anyone who knows ho to stop a treenode from being selected with
> > the mouse? I need to stay on the current node if some validation fails.
> > Although I can install an eventfilter on the QTreeWidget that catches
> > keyUp, KeyDown etc, this does not seem to work for the mouse.
> > If I trace the eventype with qDebug, I never see the mouse events pass
> > and even if I install the eventfilter on the dialog itself, it only shows
> > mouseevents when I click on the dialog itself, not when I click on the
> > TreeWidget.
>
> Try to use QTreeWidgetItem::setFlags()

Well, thanks, I've thought of that, but that would require me to set every 
TreeViewItem in the control. That seems a bit prohibitive. Especially since I 
would have to control when to enable or disable that (when some LineEdit is 
being edited etc).

There should be a an easy way, I'd rather think.

Happy coding,
Eric

--
 [ signature omitted ] 

Message 12 in thread

Hi,

The event filter must be installed on the viewport to be able to catch
mouse events.

-- 
 [ signature omitted ] 

Message 13 in thread

On Tuesday 22 January 2008 07:42:36 J-P Nurmi wrote:
> Hi,
>
> The event filter must be installed on the viewport to be able to catch
> mouse events.

Oh , would that be my dialog instead of the TreeWidget?

--
 [ signature omitted ] 

Message 14 in thread

On Tuesday 22 January 2008 07:42:36 J-P Nurmi wrote:
> Hi,
>
> The event filter must be installed on the viewport to be able to catch
> mouse events.

Thanks, figured it out. That did the trick.

Happy coding,
Eric

--
 [ signature omitted ] 

Message 15 in thread

On Tue, Jan 22, 2008 at 12:11:52AM +0100, Eric Methorst wrote:
> Well, thanks, I've thought of that, but that would require me to set every 
> TreeViewItem in the control. That seems a bit prohibitive. Especially since I 
> would have to control when to enable or disable that (when some LineEdit is 
> being edited etc).
> 
> There should be a an easy way, I'd rather think.

First way is to do some hacking with event filtering. However as for me
it's very ugly.

Try to look to Qt Model/View framework. You will be able to save some
memory if your tree is too big.

QAbstractItemModel::flags() is correct method to set/unset
Qt::ItemIsSelectable flag.

P.S. Internally QTreeWidget extends QTreeView

-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: Digital signature


Pages: Prev | 1 | 2 | 3 | Next