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

Qt-interest Archive, March 2002
Problem using QWidgetFactory and QThread


Message 1 in thread

Hi list, here is an easy one I'm sure but I can figure out why it's not
working.

I have an object that loads screens from UI files, I put it in a thread
because I want to load all my screens in parrallel (to increase loading
speed hopefully).

From another object I loop on the files in a dir and load them all in each
their own thread.
The problem is that the program jams completely with weird X errors about
sync after starting the 3rd-6th thread.
Xlib: sequence lost (0x1000d > 0x3a0) in reply type 0x7!
Xlib: sequence lost (0x10000 > 0x413) in reply type 0x4!
Xlib: sequence lost (0x10006 > 0x413) in reply type 0x1!

Can you HELP?
It is a very simple object, have a look:
hqscreenloader.h
----------------------------------------------------
class HQScreenLoader : public QThread
{
 Q_OBJECT

protected:
 QString m_sFile;

public:
 QDialog* m_pDialog;

 HQScreenLoader(const QString& sFile);
 ~HQScreenLoader();

 virtual void run();
};

hqscreenloader.cpp
--------------------------------------------------
#include <qwidgetfactory.h>
#include "hqscreenloader.h"

HQScreenLoader::HQScreenLoader(const QString& sFile) : QThread()
{
 m_sFile = sFile;
}

HQScreenLoader::~HQScreenLoader()
{
  stop();
  wait();
}

void HQScreenLoader::run()
{
 QDialog* m_pDialog = (QDialog*)QWidgetFactory::create(m_sFile);
}

Maxime Asselin
Programmer-Analyst
Research and Development


Message 2 in thread

/**************************************************************************
Hi!

    I am working in a project which is being written in C++ (actually,
using gcc/g++).  I want to implement a class (from now on, "column") which
is a container (in the following example, a vector) and is able to hold
different types (that is why it was implemented as a template below).

    Another class (from now on "data") will have a member element that is
in turn a container of "column"s. As I mentioned before I need the
"columns" to contain different types. Between those types I need basic
types (i.e. float, int, string) that is why I wish to avoid to use a
Inheritance tree (I mean, declare a basic abstract "column" class and
inherited classes that fill the "data" constainer, would be a mess). So I
thought that a templatized solution should be clenaer.

    But the point is that I didn't managed how to do so. Links on the web
are appreciated, too.

    The below code obvioulsy doesn't compile, but I hope will be usefull
to illustrate the point.

         Thanks in advance!!!


		     Claudio Tessone


****************************************************************************/
#include <string> #include <vector> #include <iostream> #include
<algorithm> template <typename T> class column: public vector< T> {
  private:
    string label;
  public:
    column(string _s="foo" ):label(_s); }; class data {
  private:
    unsigned id; //:::~ the element _theColumns_ must hold columns of
different types
    template <typename T >
    vector<column< T > *> theColumns;
  public:
    data(int _i=0):id(_i){}
    ~data(){}

//:::~ you should be able to push _column_s of different types
    void push_back(column< T > *othCol)
    {
      theColumns.push_back(othCol);
    }

//:::~ you should be able to get _column_s of different types
    column <T > *getColumn(unsigned i){return theColumns[i];}

}; int main() {
  column<int > *colI=new column<int>(10);
  column<double > *colI=new column<double>(5);
  column<string > *colI=new column<string>(3);
  data dS(1); //:::~ How do I can insert different types???
  dS.addColumn(colI);
  dS.addColumn(colD);
  dS.addColumn(colS);

 return 0;
}


-- 
 [ signature omitted ] 

Message 3 in thread

On Wed, 13 Mar 2002, Tessone, Claudio Juan wrote:

> Hi!
> 
>     I am working in a project which is being written in C++ (actually,
> using gcc/g++).  I want to implement a class (from now on, "column")
> which is a container (in the following example, a vector) and is able to
> hold different types (that is why it was implemented as a template
> below).
> 
>     Another class (from now on "data") will have a member element that
> is in turn a container of "column"s. As I mentioned before I need the
> "columns" to contain different types. Between those types I need basic
> types (i.e. float, int, string) that is why I wish to avoid to use a
> Inheritance tree (I mean, declare a basic abstract "column" class and
> inherited classes that fill the "data" constainer, would be a mess). So
> I thought that a templatized solution should be clenaer.
> 
>     But the point is that I didn't managed how to do so. Links on the
> web are appreciated, too.
> 
>     The below code obvioulsy doesn't compile, but I hope will be usefull
> to illustrate the point.
> 
First of all, keep in mind that inheriting from STL containers can easily 
lead to disaster as the STL containers don't have virtual dtors. Use 
containment instead and save yourself some potential trouble.

Whenever you want to create a list of different types, the only way about 
it is to keep a list of pointers to a common base type. Try to keep in 
mind that templates are generic only at compile time - if you think of a 
template class as a generic object at runtime you're in error.

Here's a suggestion that is close to you original attempt that should 
work (no design issues taken into consideration, and avoiding the STL 
container inheritance):

class BaseColumn
{};

template<class T1>
class Column : public BaseColumn
{
private:
  std::vector<T1> vec;
public:
// whatever functionality you need
};

class Data
{
private:
  std::vector<BaseColumn*> theColumns;
public:
  void
  push_back(BaseColumn* col)
  {
    theColumns.push_back(col);
  }
};

int main()
{
  Data dat;
  Column<double>* c1 = new Column<double>();
  BaseColumn* c2 = new Column<int>();
  dat.push_back(c1);
  dat.push_back(c2);
}

Now, if you want to do anything with the Columns held in Data, then 
common function calls for all Columns should be defined as (pure) virtual 
in BaseColumn, and possibly reimplemented. If you need to know the 
specific type of a Column at runtime you must resort to RTTI. If you end 
up doing this a lot, then it's probably a good idea to review your design. 
(As I have no idea what you're trying to do here, I can't help you there)

As a final note: 
news:comp.lang.c++ and news:comp.lang.c++.moderated is a much better arena 
for general C++ questions like this.

Have fun,
-- 
 [ signature omitted ] 

Message 4 in thread

Humm... I suspect a problem with mutual exclusion. Most Qt code is *not* reentrant (grep for QMutex in your QTDIR if you're not afraid of the result :-(( ). If you have a look to 'qwidgetfactory.cpp', you'll see there are a few global variables lying their without any exclusion access mechanism.

You should try to lock a mutex just before any call to a QWidgetFactory method an unlock it  just after the method has returned. Use a static mutex in your class if there are no other instances of QWidgetFactory in your code (of course, included any library you might link with :-) or use qApp->lock() and qApp->unlock() otherwise (this will be less efficient since the main event loop uses the same mutex)

Hope it solves your problem...

       Olive.

BTW, what is this "stop" method you've put in your code snapshot ??


> Hi list, here is an easy one I'm sure but I can figure out why it's not
> working.
>
> I have an object that loads screens from UI files, I put it in a thread
> because I want to load all my screens in parrallel (to increase loading
> speed hopefully).
>
> From another object I loop on the files in a dir and load them all in each
> their own thread.
> The problem is that the program jams completely with weird X errors about
> sync after starting the 3rd-6th thread.
> Xlib: sequence lost (0x1000d > 0x3a0) in reply type 0x7!
> Xlib: sequence lost (0x10000 > 0x413) in reply type 0x4!
> Xlib: sequence lost (0x10006 > 0x413) in reply type 0x1!
>
> Can you HELP?
> It is a very simple object, have a look:
> hqscreenloader.h
> ----------------------------------------------------
> class HQScreenLoader : public QThread
> {
>  Q_OBJECT
>
> protected:
>  QString m_sFile;
>
> public:
>  QDialog* m_pDialog;
>
>  HQScreenLoader(const QString& sFile);
>  ~HQScreenLoader();
>
>  virtual void run();
> };
>
> hqscreenloader.cpp
> --------------------------------------------------
> #include <qwidgetfactory.h>
> #include "hqscreenloader.h"
>
> HQScreenLoader::HQScreenLoader(const QString& sFile) : QThread()
> {
>  m_sFile = sFile;
> }
>
> HQScreenLoader::~HQScreenLoader()
> {
>   stop();
>   wait();
> }
>
> void HQScreenLoader::run()
> {
>  QDialog* m_pDialog = (QDialog*)QWidgetFactory::create(m_sFile);
> }
>
> Maxime Asselin
> Programmer-Analyst
> Research and Development
>
> --
> List archive and information: http://qt-interest.trolltech.com
>
--------------
Profitez de l'offre spéciale Tiscali Liberty Surf !
50% de temps en plus pendant 3 mois sur tous les forfaits Internet.

http://register.libertysurf.fr/subscribe_fr/signup.php3


Message 5 in thread

I would probably solve my problem but it would not help me load my screens
all at once (in order to increase speed).
No I already abandonned this solution anyways I am not certain it would
actually make it faster.
I will have to look for another method to load my screens faster (some can
take up to 1 second).

Thanks.

----- Original Message -----
From: <olivier.chapus@libertysurf.fr>
To: <Maxime.Asselin@htrc.com>
Cc: <qt-interest@trolltech.com>
Sent: Wednesday, March 13, 2002 2:33 PM
Subject: Re: Problem using QWidgetFactory and QThread


> Humm... I suspect a problem with mutual exclusion. Most Qt code is *not*
reentrant (grep for QMutex in your QTDIR if you're not afraid of the result
:-(( ). If you have a look to 'qwidgetfactory.cpp', you'll see there are a
few global variables lying their without any exclusion access mechanism.
>
> You should try to lock a mutex just before any call to a QWidgetFactory
method an unlock it  just after the method has returned. Use a static mutex
in your class if there are no other instances of QWidgetFactory in your code
(of course, included any library you might link with :-) or use qApp->lock()
and qApp->unlock() otherwise (this will be less efficient since the main
event loop uses the same mutex)
>
> Hope it solves your problem...
>
>        Olive.
>
> BTW, what is this "stop" method you've put in your code snapshot ??
>
>
> > Hi list, here is an easy one I'm sure but I can figure out why it's not
> > working.
> >
> > I have an object that loads screens from UI files, I put it in a thread
> > because I want to load all my screens in parrallel (to increase loading
> > speed hopefully).
> >
> > From another object I loop on the files in a dir and load them all in
each
> > their own thread.
> > The problem is that the program jams completely with weird X errors
about
> > sync after starting the 3rd-6th thread.
> > Xlib: sequence lost (0x1000d > 0x3a0) in reply type 0x7!
> > Xlib: sequence lost (0x10000 > 0x413) in reply type 0x4!
> > Xlib: sequence lost (0x10006 > 0x413) in reply type 0x1!
> >
> > Can you HELP?
> > It is a very simple object, have a look:
> > hqscreenloader.h
> > ----------------------------------------------------
> > class HQScreenLoader : public QThread
> > {
> >  Q_OBJECT
> >
> > protected:
> >  QString m_sFile;
> >
> > public:
> >  QDialog* m_pDialog;
> >
> >  HQScreenLoader(const QString& sFile);
> >  ~HQScreenLoader();
> >
> >  virtual void run();
> > };
> >
> > hqscreenloader.cpp
> > --------------------------------------------------
> > #include <qwidgetfactory.h>
> > #include "hqscreenloader.h"
> >
> > HQScreenLoader::HQScreenLoader(const QString& sFile) : QThread()
> > {
> >  m_sFile = sFile;
> > }
> >
> > HQScreenLoader::~HQScreenLoader()
> > {
> >   stop();
> >   wait();
> > }
> >
> > void HQScreenLoader::run()
> > {
> >  QDialog* m_pDialog = (QDialog*)QWidgetFactory::create(m_sFile);
> > }
> >
> > Maxime Asselin
> > Programmer-Analyst
> > Research and Development
> >
> > --
> > List archive and information: http://qt-interest.trolltech.com
> >
> --------------
> Profitez de l'offre spéciale Tiscali Liberty Surf !
> 50% de temps en plus pendant 3 mois sur tous les forfaits Internet.
>
> http://register.libertysurf.fr/subscribe_fr/signup.php3
>
>