Results 1 to 12 of 12

Thread: getting weird QPainter error QPain::begin: Paint device returned engine == 0, type: 3

  1. #1
    Join Date
    Sep 2012
    Location
    Iran
    Posts
    34
    Thanks
    33
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default getting weird QPainter error QPain::begin: Paint device returned engine == 0, type: 3

    Hello Everyone,
    I tried adding two timers to my window one for showing the time that some method is being run, the other displaying some information regarding the same method.
    to be more precise, the first timer specifies the elapsed time in the realtime , in the form of "00:00:00:00" (as for day:hour:min:sec) that shows how long a method has been being running.
    the other timer, gets the progress information of the such method, meaning how many steps have been passed and how many remains, this kind of stuff .

    the first timer interval is set to emit every 1000ms , and the second timer is set to 10 ms.

    this is how the code looks like now :
    Qt Code:
    1. void frmCustomNetwork::Init()
    2. {
    3. InitFunctions();
    4.  
    5. //set timer
    6. timer = new QTimer(0);
    7. connect(timer,SIGNAL(timeout()),this,SLOT(on_TimerTick()));
    8. timer->setInterval(1000);
    9.  
    10.  
    11. timerfast = new QTimer(this);
    12. connect(timerfast,SIGNAL(timeout()),this,SLOT(on_TimerFastTick()));
    13. timerfast->setInterval(10);
    14.  
    15. //create a new network object
    16. net = new Network(Layers,Network::TrainMode::Sequential,0);
    17.  
    18. ui->customPlot->addGraph();
    19. // give the axes some labels:
    20. ui->customPlot->xAxis->setLabel("epochs");
    21. ui->customPlot->yAxis->setLabel("errors");
    22. // set axes ranges, so we see all data:
    23. ui->customPlot->xAxis->setRange(ui->txtXaxisLower->text().toFloat(), ui->txtXaxisUpper->text().toFloat());
    24. ui->customPlot->yAxis->setRange(ui->txtYaxisLower->text().toFloat(), ui->txtYaxisUpper->text().toFloat());
    25.  
    26. ui->sliderEpoch->setMaximum(ui->txtXaxisUpper->text().toInt());
    27. }
    28.  
    29. ...
    30.  
    31.  
    32. void frmCustomNetwork::on_btnTrain_clicked()
    33. {
    34. try
    35. {
    36. if( P.size() == 0 || T.size() == 0)
    37. {
    38. QMessageBox::warning(this,"No Sample for training is set","You need to specify some samples with their respective desired outputs first");
    39. return;
    40. }
    41.  
    42. elapsedSeconds=0;
    43. timer->start();
    44. timerfast->start();
    45. connect(&watcher,SIGNAL(finished()),this,SLOT(on_ThreadJobFinshed()));
    46. future = QtConcurrent::run(this,&frmCustomNetwork::Rec,ui->chkPlot->isChecked());
    47. watcher.setFuture(future);
    48.  
    49. }
    50. catch(QException ex)
    51. {
    52. QMessageBox::critical(this,"Exception occured in on_btnTrain_clicked()",ex.what());
    53. }
    54. catch(std::exception ex)
    55. {
    56. QMessageBox::critical(this,"Exception occured in on_btnTrain_clicked()",ex.what());
    57. }
    58. catch(...)
    59. {
    60. QMessageBox::critical(this,"Exception occured on_btnTrain_clicked()","Uknown Exception occured");
    61. }
    62. }
    To copy to clipboard, switch view to plain text mode 
    and these are the timers and watchers slot respectively.
    Qt Code:
    1. void frmCustomNetwork::on_TimerTick()
    2. {
    3. try
    4. {
    5. elapsedSeconds++;
    6.  
    7. day = elapsedSeconds / (24*3600);
    8. hour = (elapsedSeconds % (24*3600)) / 3600 ;
    9. min = ((elapsedSeconds % (24*3600)) % 3600) / 60;
    10. second = ((elapsedSeconds % (24*3600)) % 3600) % 60;
    11.  
    12. ui->lblElapsedTime->setText(QString::number(day)+" : "+QString::number(hour)+" : "+QString::number(min)+" : "+QString::number(second));
    13.  
    14. }
    15. catch(QException ex)
    16. {
    17. QMessageBox::critical(this,"Exception occured in on_btnTrain_clicked()",ex.what());
    18. }
    19. catch(...)
    20. {
    21. QMessageBox::critical(this,"Exception occured in on_btnTrain_clicked()","UnExpected Exception occured! ");
    22. }
    23. }
    24.  
    25. void frmCustomNetwork::on_TimerFastTick()
    26. {
    27. QString epoch = QString::number(net->GetCurrentEpochNumber());
    28. QString patternIndex = QString::number(net->GetCurrentPatternNumber());
    29.  
    30. ui->lblCurrentEpoch->setText(epoch);
    31. ui->lblCurrentPattern->setText(patternIndex);
    32.  
    33. }
    34.  
    35.  
    36. void frmCustomNetwork::on_ThreadJobFinshed()
    37. {
    38. timer->stop();
    39. timerfast->stop();
    40. elapsedSeconds = 0;
    41. }
    To copy to clipboard, switch view to plain text mode 

    Now when the application runs, everything is just fine, when the method in question ends, the application crashes , and inside QtCreator I can see these error messages:
    Qt Code:
    1. Starting G:\ProjectsCenter\ArtificialNeuralNetworksProject\QtProject\ANN\release\Ann.exe...
    2. QPainter::begin: Paint device returned engine == 0, type: 3
    3. QPainter::setCompositionMode: Painter not active
    4. QPainter::end: Painter not active, aborted
    5. The program has unexpectedly finished.
    6. G:\ProjectsCenter\ArtificialNeuralNetworksProject\QtProject\ANN\release\Ann.exe crashed
    To copy to clipboard, switch view to plain text mode 

    Update
    For some time it seems to be running just fine, but again it fails unexpectedly : here is another error message that poped up just after executing the method in question successfully for 3 times, (on the forth time this is what I get):
    Qt Code:
    1. QMetaObject::connectSlotsByName: No matching signal for on_btnLoadCorrectSamples_clicked()
    2. QMetaObject::connectSlotsByName: No matching signal for on_btnLoadWrongSamples_clicked()
    3. QPainter::begin: Paint device returned engine == 0, type: 3
    4. QPainter::setCompositionMode: Painter not active
    5. QPainter::end: Painter not active, aborted
    6. The program has unexpectedly finished.
    7. G:\ProjectsCenter\ArtificialNeuralNetworksProject\QtProject\ANN\release\Ann.exe crashed
    To copy to clipboard, switch view to plain text mode 
    Whats causing it ?

    I also tried putting
    Qt Code:
    1. QCoreApplication::processEvents();
    To copy to clipboard, switch view to plain text mode 
    in timer slots, but that doesnt prevent crashes.
    Last edited by Hossein; 12th October 2015 at 15:00.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: getting weird QPainter error QPain::begin: Paint device returned engine == 0, typ

    Quote Originally Posted by Hossein View Post
    the first timer specifies the elapsed time in the realtime , in the form of "00:00:00:00" (as for day:hour:min:sec) that shows how long a method has been being running.
    Just as an improvement: instead of incrementing a counter, start a QElapsedTimer when you start being interested in elapsed time and use its elapsed time counting.
    The QTimer is then only used for getting the current value and updating the UI.

    That way your display is always accurate, even if the timer event is delayed, etc.

    Quote Originally Posted by Hossein View Post
    Now when the application runs, everything is just fine, when the method in question ends, the application crashes , and inside QtCreator I can see these error messages:
    What is the method in question?
    Where does it crash according to the backtrace?

    Cheers,
    _

  3. #3
    Join Date
    Sep 2012
    Location
    Iran
    Posts
    34
    Thanks
    33
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: getting weird QPainter error QPain::begin: Paint device returned engine == 0, typ

    Quote Originally Posted by anda_skoa View Post
    Just as an improvement: instead of incrementing a counter, start a QElapsedTimer when you start being interested in elapsed time and use its elapsed time counting.
    The QTimer is then only used for getting the current value and updating the UI.

    That way your display is always accurate, even if the timer event is delayed, etc.


    What is the method in question?
    Where does it crash according to the backtrace?

    Cheers,
    _
    OK , Ill change that to QElapsedTimer,
    for the method in question , here it is :
    Qt Code:
    1. bool frmCustomNetwork::Rec(bool plot)
    2. {
    3.  
    4. if(!InitNetwork())
    5. return false;
    6.  
    7. auto errorVect = net->Train(false);
    8. errorVector.clear();
    9. errorVector = QVector<double>::fromStdVector(errorVect) ;
    10. if (plot)
    11. {
    12. epochRange.clear();
    13. for(int i =0; i < errorVector.size(); i++)
    14. epochRange.push_back(i);
    15.  
    16. InitGraphSettings(errorVect);
    17.  
    18. ui->customPlot->graph(0)->setData(epochRange,errorVector );
    19. ui->customPlot->replot();
    20.  
    21. }
    22.  
    23. if(ui->chkdislayErrors->isChecked())
    24. {
    25. ui->txtInfo->setText(QString::number(errorVector.size()));
    26. for(int i =0; i < errorVector.size(); i++)
    27. ui->txtInfo->append(QString::number(errorVector[i]) );
    28. }
    29. return true;
    30. }
    To copy to clipboard, switch view to plain text mode 

    which calls these :
    Qt Code:
    1. bool frmCustomNetwork::InitNetwork()
    2. {
    3. if(Layers.size()==0)
    4. {
    5. QMessageBox::critical(this,"No Layer is set","No Layer is added, please add some layers first");
    6. return false;
    7. }
    8.  
    9. bool output =false,hidden=false;
    10. for(auto &l:Layers)
    11. {
    12. if ( l->GetType() == Layer::LayerType::Output)
    13. output = true;
    14. else if ( l->GetType() == Layer::LayerType::Hidden)
    15. hidden = true;
    16. }
    17.  
    18. if (!(output && hidden))
    19. {
    20. QMessageBox::critical(this,"Not enough layers are set","You must alteast have one or more hidden layers and only one output layer");
    21. return false;
    22. }
    23.  
    24. Network::TrainMode mode;
    25. int count=0;
    26. Layers[0]->SetAsFirstLayer(true);
    27.  
    28. while (count < Layers.size())
    29. {
    30. Layer* layer = Layers[count];
    31. if (layer->GetType() != Layer::LayerType::Output)
    32. {
    33. Layer* layer2 = Layers[count+1];
    34. layer->ConnectToLayer(layer2,true);
    35. }
    36. count++;
    37. }
    38.  
    39. if(ui->rdBtnSeq->isChecked())
    40. mode = Network::TrainMode::Sequential;
    41. else
    42. mode = Network::TrainMode::Batch;
    43.  
    44.  
    45.  
    46. net->SetLayers(Layers);
    47. net->SetMode(mode);
    48. net->SetEpoch(ui->txtEpoch->text().toInt());
    49. net->SetLearningRate(ui->txtLearningRate->text().toFloat());
    50. net->SetInputs(P);
    51. net->SetTargets(T);
    52. net->SetErrorVectorStatus(ui->chkErrorsSquared->isChecked());
    53.  
    54.  
    55. return true;
    56. }
    57.  
    58. void frmCustomNetwork::InitGraphSettings( vector<double>& res)
    59. {
    60. auto result = std::minmax_element(res.begin(), res.end());
    61. double errorMin = *result.first;//min
    62. double errorMax = *result.second;//max
    63. ui->txtYaxisLower->setText(QString::number(errorMin));
    64. ui->txtYaxisUpper->setText(QString::number(errorMax));
    65.  
    66. ui->sliderEpoch->setValue(ui->txtEpoch->text().toInt());
    67. on_sliderEpoch_sliderMoved( ui->sliderEpoch->value());
    68. }
    To copy to clipboard, switch view to plain text mode 


    Added after 1:


    I guess I found out what the cause is. I guess its because of the spawned thread trying to access and modify the UI components. When I commented the plot section, the crashes stopped.
    I need to investigate much further though to make sure this is the casue.
    In the meantime , if this is the case, How should I solve this ?
    Thanks in advacne
    Last edited by Hossein; 12th October 2015 at 17:40.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: getting weird QPainter error QPain::begin: Paint device returned engine == 0, typ

    Only the main thread (the thread that created QApplication instance and runs QApplication::exec()) can access UI components.

    If you have a thread that generates data that needs to be displayed, you have various methods at your disposal.
    The easiest one is usually to emit a signal with the data and connect it to a slot of an object running in the main thread.

    Cheers,
    _

  5. #5
    Join Date
    Sep 2012
    Location
    Iran
    Posts
    34
    Thanks
    33
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: getting weird QPainter error QPain::begin: Paint device returned engine == 0, typ

    Quote Originally Posted by anda_skoa View Post
    Only the main thread (the thread that created QApplication instance and runs QApplication::exec()) can access UI components.

    If you have a thread that generates data that needs to be displayed, you have various methods at your disposal.
    The easiest one is usually to emit a signal with the data and connect it to a slot of an object running in the main thread.

    Cheers,
    _
    I'm lost here, I would greatly appreciate a sample demonstrating what you are suggesting.

  6. #6
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: getting weird QPainter error QPain::begin: Paint device returned engine == 0, typ

    How are you handling cancellation and cleanup of the the QFuture object and its associated background thread if the program is terminated?

  7. #7
    Join Date
    Sep 2012
    Location
    Iran
    Posts
    34
    Thanks
    33
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: getting weird QPainter error QPain::begin: Paint device returned engine == 0, typ

    Quote Originally Posted by ChrisW67 View Post
    How are you handling cancellation and cleanup of the the QFuture object and its associated background thread if the program is terminated?
    Do I have to clean QFuture ? ! Isn't the background thread itself terminated when it finishes its job?

  8. #8
    Join Date
    Sep 2012
    Location
    Iran
    Posts
    34
    Thanks
    33
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: getting weird QPainter error QPain::begin: Paint device returned engine == 0, typ

    Ok, I managed to create a thread but I get an errror message saying :

    Qt Code:
    1. QObject::connect: Cannot queue arguments of type 'std::vector<double>'
    2. (Make sure 'std::vector<double>' is registered using qRegisterMetaType().)
    To copy to clipboard, switch view to plain text mode 

    This is how I used the thread:
    Qt Code:
    1. void frmCustomNetwork::on_btnTrain_clicked()
    2. {
    3. try
    4. {
    5. if( P.size() == 0 || T.size() == 0)
    6. {
    7. QMessageBox::warning(this,"No Sample for training is set","You need to specify some samples with their respective desired outputs first");
    8. return;
    9. }
    10.  
    11. if(!InitNetwork())
    12. return ;
    13.  
    14. timer->start();
    15. timerfast->start();
    16.  
    17. trainThread = new TrainInThread(net);
    18. connect(trainThread,SIGNAL(processDone(std::vector<double>)),this,SLOT(OnTrainingFinished(std::vector<double>)));
    19. trainThread.start();
    20. }
    21. catch(QException ex)
    22. {
    23. QMessageBox::critical(this,"Exception occured in on_btnTrain_clicked()",ex.what());
    24. }
    25. catch(std::exception ex)
    26. {
    27. QMessageBox::critical(this,"Exception occured in on_btnTrain_clicked()",ex.what());
    28. }
    29. catch(...)
    30. {
    31. QMessageBox::critical(this,"Exception occured on_btnTrain_clicked()","Uknown Exception occured");
    32. }
    33. }
    34.  
    35. void frmCustomNetwork::OnTrainingFinished(std::vector<double> errorVect)
    36. {
    37. timer->stop();
    38. timerfast->stop();
    39.  
    40. errorVector.clear();
    41. errorVector = QVector<double>::fromStdVector(errorVect);
    42.  
    43. if (ui->chkPlot->isChecked())
    44. {
    45. epochRange.clear();
    46. for(int i =0; i < errorVector.size(); i++)
    47. epochRange.push_back(i);
    48.  
    49. InitGraphSettings(errorVect);
    50.  
    51. ui->customPlot->graph(0)->setData(epochRange,errorVector );
    52. ui->customPlot->replot();
    53.  
    54. }
    55.  
    56. if(ui->chkdislayErrors->isChecked())
    57. {
    58. ui->txtInfo->setText(QString::number(errorVector.size()));
    59. for(int i =0; i < errorVector.size(); i++)
    60. ui->txtInfo->append(QString::number(errorVector[i]) );
    61. }
    62. }
    To copy to clipboard, switch view to plain text mode 
    Here is my implementation of QThread :
    Qt Code:
    1. #ifndef TRAININGINTHREAD
    2. #define TRAININGINTHREAD
    3. #include <QThread>
    4. #include <QString>
    5.  
    6. class Network;
    7.  
    8. class TrainInThread :
    9. public QThread
    10. {
    11. Q_OBJECT //Don't forget this MACRO to let this class emit SIGNALS
    12.  
    13. public:
    14. TrainInThread(Network* net,bool showTrace =false );
    15. ~TrainInThread();
    16. void run();
    17.  
    18. signals:
    19. void processDone(std::vector<double>);//SIGNAL to show that some process have been done
    20.  
    21. private:
    22. Network* _net;
    23. bool _showTrace;
    24.  
    25. };
    26. #endif // TRAININGINTHREAD
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include "../../ArtificialNeuralNetworksProject/Network.h"
    2. #include "traininginthread.h"
    3. #include <QDebug>
    4. TrainInThread::TrainInThread(Network* net, bool showTrace):_showTrace(showTrace)
    5. {
    6. _net = net;
    7. }
    8.  
    9. TrainInThread::~TrainInThread()
    10. {}
    11.  
    12. void TrainInThread::run()
    13. {
    14. //Do heavy process
    15. auto errorVect = _net->Train(_showTrace);
    16. //Emit a SIGNAL with the error vector
    17. emit processDone(errorVect);
    18. }
    To copy to clipboard, switch view to plain text mode 
    Whats wrong with this code?
    I got the idea from here and here


    Added after 1 13 minutes:


    found the cause, I had to place this inside the TrainingInThread's constructor
    Qt Code:
    1. qRegisterMetaType< std::vector<double> >( "std::vector<double>" );//for signal to be able to send std::vector<double>
    To copy to clipboard, switch view to plain text mode 
    Last edited by Hossein; 13th October 2015 at 06:47.

  9. #9
    Join Date
    Sep 2012
    Location
    Iran
    Posts
    34
    Thanks
    33
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: getting weird QPainter error QPain::begin: Paint device returned engine == 0, typ

    By the way how can i terminate an existing thread?
    when I do
    if(trainThread && trainThread->isRunning())
    trainThread->exit();

    it just gives me an exception 0xc0000005, which accessing a nullpointer usually !
    I am doing this before I create new threads, (suppose user clicks on the same button twice, and while the previous thread is still running, a new one is spawned and the a crash happens here, I am trying to prevent this in fact.
    So how should I go about this one?

  10. #10
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: getting weird QPainter error QPain::begin: Paint device returned engine == 0, typ

    QThread::exit() ends the thread's event loop, your thread does not run an event loop.
    It will exit as soon as its run() method returns.

    There is no save way to "end" a thread without its cooperation.

    Cheers,
    _

  11. The following user says thank you to anda_skoa for this useful post:

    Hossein (13th October 2015)

  12. #11
    Join Date
    Sep 2012
    Location
    Iran
    Posts
    34
    Thanks
    33
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: getting weird QPainter error QPain::begin: Paint device returned engine == 0, typ

    Quote Originally Posted by anda_skoa View Post
    QThread::exit() ends the thread's event loop, your thread does not run an event loop.
    It will exit as soon as its run() method returns.

    There is no save way to "end" a thread without its cooperation.

    Cheers,
    _
    Thanks, so how can I do that ?
    do you mean incorporating an event loop inside the Train() method ?
    Isn't there any break method that would ungracefully kill a thread! :-/

  13. #12
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: getting weird QPainter error QPain::begin: Paint device returned engine == 0, typ

    Quote Originally Posted by Hossein View Post
    do you mean incorporating an event loop inside the Train() method ?
    If you don't need event processing then just checking a stop flag would be sufficient.

    Quote Originally Posted by Hossein View Post
    Isn't there any break method that would ungracefully kill a thread! :-/
    You can terminate a thread, but then your application is in an unknown state.
    It could crash, deadlock, leak memory, etc., because it all depends on what the thread was doing, which resources it held and so on when it was terminated.

    Hence "no save way" of doing it other then asking the thread to stop doing what it is doing. Or rather build exit points into whatever code is being executed, because there you know about those things.

    If you don't have control over what the thread's "payload" code is doing, then you could consider running it in a separate process.
    Unless the code uses some system global resources (e.g. explicit file locks, system semaphores), it can be safely terminated by the operating system.

    Cheers,
    _

  14. The following user says thank you to anda_skoa for this useful post:

    Hossein (13th October 2015)

Similar Threads

  1. Replies: 1
    Last Post: 30th December 2013, 17:06
  2. Error Message "Paint device returned engine == 0, type:1"
    By yuzhouzhiwai in forum Qt Programming
    Replies: 5
    Last Post: 30th April 2012, 09:33
  3. Replies: 0
    Last Post: 27th April 2012, 13:54
  4. Replies: 4
    Last Post: 25th February 2011, 09:01
  5. paint device returned engine == 0, type: 3
    By MarkoSan in forum Qt Programming
    Replies: 14
    Last Post: 12th December 2007, 10:42

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.