PDA

View Full Version : Problem with QMainWindow



bbad68
2nd March 2010, 19:50
Hi,

My application generates a 3d-model using vtk and displays it in a qvtkwidget. When the user clicks the 'Generate' button in one of the main window's dialogs the program generates the model, which takes a significant amount of time. My problem is that while the model is loading, I can't access the main window at all; I can't maximize, minimize, move the window, or even click the 'Cancel' button on the QProgressDialog that appears to show the model's progress. How can I fix this?

franz
2nd March 2010, 20:06
The model is being loaded in the main thread. While it is loading the model, the GUI isn't updated. You should load the model in a separate thread if possible. This will keep your main thread and thereby your application responsive. (look into QtConcurrent).

schnitzel
2nd March 2010, 20:26
You must be missing the QCoreApplication::processEvents() call inside your loop that loads the model.

for example:


QProgressDialog progress("Receiving File...", "Cancel",0,fileSize, this);
progress.setWindowModality(Qt::WindowModal);
progress.show();

m_timeout = 10;
timer->start();
QProgressDialog cancelXfer("Canceling transfer, please wait...",QString(),0,0,this);
cancelXfer.setWindowModality(Qt::WindowModal);
bool flag = true;

while(m_timeout > 0)
{
if(!progress.wasCanceled())
{
ret = FT_Read(fth, (unsigned char *)dbuf.data(), num2rd, &numrd);
if(numrd > 0)
{
rxf.write(dbuf,numrd);
byteCount += numrd;
m_timeout = 4;
progress.setValue(byteCount);
}
}
else
{
if (flag)
{
ret = FT_Write(fth, (unsigned char * ) "a",1, &numwr);
flag = false;
cancelXfer.show();
}

}


QCoreApplication::processEvents();
}

if (progress.wasCanceled())
cancelXfer.reset();
progress.reset();


timer->stop();

franz
2nd March 2010, 20:32
OP stated that the cancel button was unusable. If the cancel button doesn't even visibly react to the mouse click, you still need to do multithreading. If the button does react, you have to connect it's clicked() signal to a slot that handles the actual abort.

schnitzel
2nd March 2010, 20:35
@franz
cancel button is probably unusable due to absence of processEvents. I updated the sample code.
Of course if there are any blocking calls when loading the 3d model, then yes one would have to resort to multithreading.

bbad68
2nd March 2010, 22:39
The 'Cancel' button in the dialog does not react at all when clicked. I can see the progress bar working, but the entire window remains inaccessable while the model is being generated.

I just found the following in the documentation:
"Multithreaded programming is also a useful paradigm for performing time-consuming operations without freezing the user interface of an application."

It looks like multithreading is the solution. Unfortunately, I have no idea how multithreading works :o. Any recommendations for what I could read to learn the basics? The documentation had some suggestions, but they were all in the form of paperback books that I'd have to buy from amazon.com, which I don't really want to do. It's not a very complicated operation; it's only a very small section of code in which I'd have to do multithreading. I can post the code as well, if you think that it would be a better use of my time.

schnitzel
2nd March 2010, 22:48
The 'Cancel' button in the dialog does not react at all when clicked. I can see the progress bar working, but the entire window remains inaccessable while the model is being generated.

I just found the following in the documentation:
"Multithreaded programming is also a useful paradigm for performing time-consuming operations without freezing the user interface of an application."

It looks like multithreading is the solution. Unfortunately, I have no idea how multithreading works :o. Any recommendations for what I could read to learn the basics? The documentation had some suggestions, but they were all in the form of paperback books that I'd have to buy from amazon.com, which I don't really want to do. It's not a very complicated operation; it's only a very small section of code in which I'd have to do multithreading. I can post the code as well, if you think that it would be a better use of my time.

If the progressbar still updates, then you are just missing the processEvents call. Look at the example I provided.


Multithreading is great, if you know what you are doing :)

bbad68
2nd March 2010, 23:28
I have no idea what QCoreApplication::processEvents() actually does, but somehow it works :D

Thanks a lot!

schnitzel
2nd March 2010, 23:43
I have no idea what QCoreApplication::processEvents() actually does, but somehow it works :D

Thanks a lot!

Glad I could help.

Just look up the help info on QCoreApplication::processEvents, which describes what it does and also mentions exactly your issue.

Multithreading is not that easy to use and misunderstood by many. I will always try to avoid it if possible.

Making code thread-safe is an art and not to mention the complexity of debugging a multithreaded app.