PDA

View Full Version : I`m doing it wrong....



KillGabio
12th February 2012, 18:27
Hi guys im having kind of a headache understanding threads in Qt.
I`ve already read some post about QThread and the You are doing it blog entry but somehow I cant understand the full concep...
My idea is to show a loading widget while i load my application data. So far I ve the following code:


#include <QtGui/QApplication>
#include <QObject>
#include "waitthread.h"
#include "loadthread.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QApplication::setStyle (new IconSize ());

LoadThread * load_thread = new LoadThread ();
WaitThread * wait_thread = new WaitThread ();

QObject::connect (load_thread, SIGNAL(load_finished()), wait_thread, SLOT(loading_finished()));

load_thread->start ();
wait_thread->start ();

return a.exec ();
}


the loadthread.cpp:


LoadThread::LoadThread()
{
mainWin = new MainWindow ();
}

void LoadThread::run (){
//--------------------do some stuff
emit load_finished ();
emit load_finished ();
show_mainWin ();
}

void LoadThread::show_mainWin (){
mainWin->show ();
}


And the waitThread.cpp


#include "waitthread.h"

WaitThread::WaitThread()
{
loadwidg = new LoadingWidget ();
loadwidg->show ();
}

void WaitThread::run (){
}

void WaitThread::loading_finished (){
loadwidg->close ();
delete loadwidg;
this->terminate ();
}


I think that the signal is received because the loading widget is closed...but mainWin only pops up for a split sec, like the object Qthread is destroyed...I know that im designing this the wrong way...hope someone can give a hand to fully understand this...

wysota
12th February 2012, 19:37
Threads can't operate on widgets. Period.

Read this: Keeping the GUI Responsive

KillGabio
12th February 2012, 21:00
Ok I read the article. But still cannot crack it. Somehow I think my best course of action to achieve what I want (show a widget smoothly while mainWindow and its components are loaded) is to use the QTimer::singleShot.
I´ve changed my whole code but i cannot get the whole idea of the timer I guess
So far I have this:



#include <QtGui/QApplication>
#include <QObject>
#include <QDesktopWidget>
#include "loadthread.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QApplication::setStyle (new IconSize ());

LoadingWidget *loadwidg = new LoadingWidget ();
loadwidg->show ();
QApplication::setStyle (new IconSize ());
MainWindow mainWin;
LoadThread * load_thread = new LoadThread (&mainWin);
QObject::connect (load_thread, SIGNAL(load_finished()), loadwidg, SLOT(load_finished()));
QTimer::singleShot (0,load_thread, SLOT(load()));
mainWin.show ();
return a.exec ();
}

And the load class does this

#include "loadthread.h"

LoadThread::LoadThread(MainWindow * mainWin)
{
this->mainWin = mainWin;
}

void LoadThread::load (){

mainWin->setWindowTitle("Los Taninos Vinoteca");
mainWin->setWindowFlags (Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint);
//centrar imagen
mainWin->setGeometry( QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter,mainWin->size(),qApp->desktop()->availableGeometry()));
//some not interesting code
if (handler >= 0 && aux ==0 && capacidad >0){
mainWin->setHandler (handler);
}else{
if (capacidad == 0){
QMessageBox::critical (0, QString ("NO MORE REGISTERS TO STORE DATA"), QString ("No quedan más registros para guardar información fiscal\n\nNo se podrá realizar ninguna operación\nrelacionada con el controlador."), QMessageBox::Ok);
}else QMessageBox::information (0, QString ("NO FISCAL PRINTER"),QString ("No se ha encontrado el controlador fiscal\nconectado, no se podrá facturar"));
mainWin->setHandler (0);
}
emit load_finished ();
}

Doing this the loading widget still not running at 40ms :(

wysota
12th February 2012, 21:05
What exactly would you expect this code to do?

KillGabio
12th February 2012, 21:10
To show the widget (consisting of a label and Qmovie attached to another label) and do loading operations without afecting the .gif movie smooth visualization. My problem is that the operations of loading slow the presentation of the gif and I dont want that

ChrisW67
12th February 2012, 21:40
My idea is to show a loading widget while i load my application data. So far I ve the following code:
QSplashScreen seems a perfect place to start.

KillGabio
12th February 2012, 21:58
I`ve read the documentatios of splashscreen, but I think it isnt possible to display .gif , is it? As it is not editable i cannot add a for example two labels as I have, and the fact that by clicking it, it disappears I dont like it, lol...

ChrisW67
12th February 2012, 22:16
Let's see:

QSplashScreen displays a pixmap, which could be from a GIF. An animated GIF won't work as-is, but you could subclass QSplashScreen, and use a QMovie to provide frame-by-frame pixmaps. Your main problem would be calling qApp->processEvents() often enough.
QSplashScreen displays a message that can be changed as the load process continues
QSplashScreen disappears when the mouse is clicked (by default and user expectation) but you could override the mousePressEvent() and ignore that.


Worst case, you could look at how QSpashScreen is built and mimic it.

It's only a suggestion.

wysota
12th February 2012, 22:20
If you really want your program to waste processing power on showing an animation then display the animation in the main thread and do the loading in another thread but focus on loading data and not manipulating widgets. Widgets can only be accessed from the main thread. Other than that, you can use the "solving the problem step by step" approach from the article I gave you a link to but it won't be as easy as writing play() and load().

KillGabio
12th February 2012, 22:23
This is the class i`ve implemented so far....the problem is that as it is a Widget tha gif is shown sooo slow i can go to the bath come back and it hasn`t move. When the mainWindow is displayed I can see that the gif of the widget moves like super fast...like when a movie is freezed and when the focus returns it starts to move like x10 speed..Maybe the delay is produced by my code.. I dont know



LoadingWidget::LoadingWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::LoadingWidget)
{
ui->setupUi(this);
this->setWindowTitle ("Loading Gestion Vinoteca");
var_timer = 0;
load_gif = new QMovie (":/ImagesMilk/Iconos/zombiewalk.gif");
ui->label_gif->setMovie (load_gif);
timer = new QTimer (this);
this->setWindowFlags (Qt::Window |Qt::CustomizeWindowHint);
connect (timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start (1000);
load_gif->start ();
}

LoadingWidget::~LoadingWidget()
{
delete timer;
delete load_gif;
delete ui;
}

void LoadingWidget::update (){
var_timer = (var_timer+1) %4;
switch (var_timer){
case 0:
ui->label_text_loading->setText ("Loading");
break;
case 1:
ui->label_text_loading->setText ("Loading.");
break;
case 2:
ui->label_text_loading->setText ("Loading..");
break;
case 3:
ui->label_text_loading->setText ("Loading...");
break;
}
}

void LoadingWidget::load_finished (){
this->close ();
}

wysota
12th February 2012, 22:48
Are you sure you read the article I gave you with proper care? By the way, update() is a method defined in QWidget that has a particular meaning.

KillGabio
12th February 2012, 22:54
I must admit I read it with proper care, but not with proper understanding. As you and I said a good approach is the "step by step"...but im also finding it difficult to implement..

wysota
13th February 2012, 01:02
Can't eat the cake and still have the cake. You must put some effort to have results.

KillGabio
13th February 2012, 01:58
Can't eat the cake and still have the cake. You must put some effort to have results.

Jajaja I know you are right I just wish I have more time to finish it properly. I know im duplicating code and some other mistakes, the thing is that im leaving town this Wends and I need to finish the app...So this last month has been very mentally busy for me: learning qt, oracle and the fucking fiscal printer API that by the way its documentation is badly written so I had to almost guess every command (thought installing the OCX would be more difficult than communicating with Strings, guess I was wrong lol)...Im going to sue those Hasar developing team...All that said Im very grateful to you and chris specially for all the help given ;)

And again sorry if i had some spellmistakes lol