Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QPixmap and GUI application - how end my app?
QtWS25 Last Chance

QPixmap and GUI application - how end my app?

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 3 Posters 1.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    TomNow99
    wrote on last edited by TomNow99
    #1

    Hello,
    I have a problem with ending my GUI Application. Often I get warnings:

    QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication
    QPixmap: Must construct a QGuiApplication before a QPixmap
    

    My code:

                while(1)
                {
                         QPixmap pixmap = qApp->screens().at(0)->grabWindow(QDesktopWidget().winId());
                         label->setPixmap(pixmap.scaled(label->width(), label->height(), Qt::KeepAspectRatio));
                }
    

    When I close my App, my App is deleted, but grabWindow function is still working, but there is no qApp when pixmap is ready.

    How can I wait until grabWindow() will be ready and next I'll end my app.

    EDIT:
    One solution is to add "Sleep(1000)" in the MainWindow destructor before delete ui. It works, but I think there is better solution

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi
      Do you have that code in a thread
      as while(1) is pure evil for a GUI app.

      T 1 Reply Last reply
      1
      • mrjjM mrjj

        Hi
        Do you have that code in a thread
        as while(1) is pure evil for a GUI app.

        T Offline
        T Offline
        TomNow99
        wrote on last edited by
        #3

        @mrjj Yes, the while(1) is in the run() function in the other thread

        mrjjM 1 Reply Last reply
        0
        • T TomNow99

          @mrjj Yes, the while(1) is in the run() function in the other thread

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by mrjj
          #4

          @TomNow99

          Hi
          You have to fix your thread code then so it can exit the loop on some condition.
          then in the main app do

          connect(qApp, &QApplication::aboutToQuit, Yourthread, [=]{
          Yourthread->quit();
          Yourthread->wait();
          });

          Did you override thread::run ?

          1 Reply Last reply
          0
          • T Offline
            T Offline
            TomNow99
            wrote on last edited by
            #5

            @mrjj My current code is:

            class threadx: public QThread
            {
                Q_OBJECT
            public:
            
                threadx(clickableLabel * l, int i);
                void run() override;
                void setKill();
            private:
                clickableLabel* label;
                int whichOne;
                bool kill = false;
            };
            
            threadx::threadx(clickableLabel * l, int i): label(l), whichOne(i){}
            
            void threadx::run()
            {
                while(1)
                {
                    QPixmap pixmap = qApp->screens().at(0)->grabWindow(QDesktopWidget().winId());
                    label->setPixmap(pixmap.scaled(label->width(), label->height(), Qt::KeepAspectRatio));
                    
                    if(kill)
                    {
                        terminate();
                        wait();
                    }
                }
            }
            
            void threadx::setKill()
            {
                kill = true;
            }
            

            And In my mainWindow I only create QVector with xthreads:

            threads.append(new threadx(wektor.last(),i));
            

            After 200 msec I start them:

                for(int i=0;i<threadsAmount;i++)
                {
                    threads[i]->start();
                }
            

            And in mainWindow destructor I have:

                for(auto x: threads)
                {
                    x->setKill();
                }
            
                Sleep(1000);
            
                delete ui;
            
            1 Reply Last reply
            0
            • mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by mrjj
              #6

              Hi
              How can this even run ?
              Mine says ASSERT failure in QWidget: "Widgets must be created in the GUI thread.",
              since you have a QLabel ? in the thread.

              Also you use wait inside the run and doc says
              https://doc.qt.io/qt-5/qthread.html#wait
              The thread associated with this QThread object has finished execution (i.e. when it returns from run()).

              so not sure thats is nice inside run

              Also you use terminate which is brute force and should not be used ( often)

              Try this

              MainWindow::~MainWindow()
              {
              
                  for (auto x : threads) {
                      x->requestInterruption();
                      x->wait();
                      delete x;
                  }
              
              
                  delete ui;
              }
              
              void threadx::run()
              {
                  while ( ! QThread::currentThread()->isInterruptionRequested()) {
              
                      QPixmap pixmap = qApp->screens().at(0)->grabWindow(QDesktopWidget().winId());
                      label->setPixmap(pixmap.scaled(label->width(), label->height(), Qt::KeepAspectRatio));
              
                  }
              }
              
              

              But im really, really surprised if you can use a Qwidget inside a thread. Its an instant crash for me.

              1 Reply Last reply
              2
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Hi,

                Beside the points made by @mrjj, terminate shall only be used as a last resort. It will not allow for any cleanup to happen properly.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                1
                • T Offline
                  T Offline
                  TomNow99
                  wrote on last edited by TomNow99
                  #8

                  @mrjj @SGaist I create QLabels in my main thread. The next threads get only pointers to labels and change pixmaps.

                  PseudoCode is:

                  my main thread

                  for(int i=0; i<screensAmount();i++)
                  {
                      vectorLabels[i] = new QLabel();  // here there are clickableLabels which are QLabels and I can click on them
                      vectorthreadsx[i] = new threadx(vectorLabels[i], i);
                      grid->addWidget(vectorLabels[i]);
                  }
                  QTimer::singleShot(200, this, slotStart());
                  
                  
                  slotStart():
                  {
                       for(int i=0; i<screensAmount();i++)
                       {
                           vectorXthreads[i] ->start();
                       }
                  }
                  

                  And my threadx Class:

                  threadx::threadx(clickableLabel * l, int i): label(l), whichOne(i){}
                  
                  void threadx::run()
                  {
                      while(1)
                      {
                          QPixmap pixmap = qApp->screens().at(0)->grabWindow(QDesktopWidget().winId());
                          label->setPixmap(pixmap.scaled(label->width(), label->height(), Qt::KeepAspectRatio));
                          
                          if(kill)
                          {
                              terminate();
                              wait();
                          }
                      }
                  }
                  

                  And the second question:

                  I would like to get screen in Linux. In windows I have to do only:

                  QPixmap pixmap = qApp->screens().at(0)->grabWindow(QDesktopWidget().winId());
                  

                  But in Linux this isn't work. So what can I do?

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    You are accessing a GUI element from a different thread which as already said shall not be done. QPixmap is a class ride to the graphics environment so it follows the same rule. If you to process some image in a different thread, use QImage and send that back to the original thread.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    2

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved