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. Paint to QWidget but not main window
Forum Updated to NodeBB v4.3 + New Features

Paint to QWidget but not main window

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 2 Posters 2.0k 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.
  • supersteveS Offline
    supersteveS Offline
    supersteve
    wrote on last edited by supersteve
    #1

    Hi

    I am using the scribble example as a template and starting point. What i want to do is create a second window that will copy whatever is drawn on the scribble application.

    I have modified the paintEvent to copy the output to a second window.

    void ScribbleArea::paintEvent(QPaintEvent *event)
    //! [13] //! [14]
    {
        QPainter painter(this);
        QRect dirtyRect = event->rect();
        painter.drawImage(dirtyRect, image, dirtyRect);
    
        QPainter painter2(secondDisplay);
     //   QRect dirtyRect2 = event->rect();
     //   painter2.drawImage(dirtyRect, image, dirtyRect);
    }
    //! [14]
    

    The second blank window shows but i get the following error when i start drawing

    QWidget::paintEngine: Should no longer be called
    QPainter::begin: Paint device returned engine == 0, type: 1
    QWidget::paintEngine: Should no longer be called
    QPainter::begin: Paint device returned engine == 0, type: 1
    QWidget::paintEngine: Should no longer be called
    

    My second window is created in the scribblearea.cpp file

    ScribbleArea::ScribbleArea(QWidget *parent)
        : QWidget(parent)
    {
        setAttribute(Qt::WA_StaticContents);
        modified = false;
        scribbling = false;
        myPenWidth = 1;
        myPenColor = Qt::blue;
    
      //  projector = new ScribbleArea;   // create the display for the projector
       secondDisplay= new QWidget;
        secondDisplay->setWindowFlags(Qt::FramelessWindowHint);
        secondDisplay->resize(800,480);
        secondDisplay->show();
    
    }
    

    and a pointer created in the header

    private:
        void drawLineTo(const QPoint &endPoint);
        void resizeImage(QImage *image, const QSize &newSize);
    
        QWidget *secondDisplay;
    
        bool modified;
        bool scribbling;
        int myPenWidth;
        QColor myPenColor;
        QImage image;
        QPoint lastPoint;
    

    Steve

    raven-worxR 1 Reply Last reply
    0
    • supersteveS supersteve

      Hi

      I am using the scribble example as a template and starting point. What i want to do is create a second window that will copy whatever is drawn on the scribble application.

      I have modified the paintEvent to copy the output to a second window.

      void ScribbleArea::paintEvent(QPaintEvent *event)
      //! [13] //! [14]
      {
          QPainter painter(this);
          QRect dirtyRect = event->rect();
          painter.drawImage(dirtyRect, image, dirtyRect);
      
          QPainter painter2(secondDisplay);
       //   QRect dirtyRect2 = event->rect();
       //   painter2.drawImage(dirtyRect, image, dirtyRect);
      }
      //! [14]
      

      The second blank window shows but i get the following error when i start drawing

      QWidget::paintEngine: Should no longer be called
      QPainter::begin: Paint device returned engine == 0, type: 1
      QWidget::paintEngine: Should no longer be called
      QPainter::begin: Paint device returned engine == 0, type: 1
      QWidget::paintEngine: Should no longer be called
      

      My second window is created in the scribblearea.cpp file

      ScribbleArea::ScribbleArea(QWidget *parent)
          : QWidget(parent)
      {
          setAttribute(Qt::WA_StaticContents);
          modified = false;
          scribbling = false;
          myPenWidth = 1;
          myPenColor = Qt::blue;
      
        //  projector = new ScribbleArea;   // create the display for the projector
         secondDisplay= new QWidget;
          secondDisplay->setWindowFlags(Qt::FramelessWindowHint);
          secondDisplay->resize(800,480);
          secondDisplay->show();
      
      }
      

      and a pointer created in the header

      private:
          void drawLineTo(const QPoint &endPoint);
          void resizeImage(QImage *image, const QSize &newSize);
      
          QWidget *secondDisplay;
      
          bool modified;
          bool scribbling;
          int myPenWidth;
          QColor myPenColor;
          QImage image;
          QPoint lastPoint;
      

      Steve

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by raven-worx
      #2

      @supersteve
      every widget is only allowed to paint to itself in the paintEvent() handler
      You you need to change your design.

      When the data changes and a repaint is needed you should notify secondDisplay about the change and set the necessary data and let it repaint itself.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      1
      • supersteveS Offline
        supersteveS Offline
        supersteve
        wrote on last edited by
        #3

        Thanks for the response, i have attempted what you suggested with not much luck.

        I created a function within the ScribbleArea class that returns the QImage image.

        I then used then used the existing Help menu button (just for testing) to update the Widget but i still get the same error.

        /****************************************************************************
        **
        ** Copyright (C) 2016 The Qt Company Ltd.
        ** Contact: https://www.qt.io/licensing/
        **
        ** This file is part of the examples of the Qt Toolkit.
        **
        ** $QT_BEGIN_LICENSE:BSD$
        ** Commercial License Usage
        ** Licensees holding valid commercial Qt licenses may use this file in
        ** accordance with the commercial license agreement provided with the
        ** Software or, alternatively, in accordance with the terms contained in
        ** a written agreement between you and The Qt Company. For licensing terms
        ** and conditions see https://www.qt.io/terms-conditions. For further
        ** information use the contact form at https://www.qt.io/contact-us.
        **
        ** BSD License Usage
        ** Alternatively, you may use this file under the terms of the BSD license
        ** as follows:
        **
        ** "Redistribution and use in source and binary forms, with or without
        ** modification, are permitted provided that the following conditions are
        ** met:
        **   * Redistributions of source code must retain the above copyright
        **     notice, this list of conditions and the following disclaimer.
        **   * Redistributions in binary form must reproduce the above copyright
        **     notice, this list of conditions and the following disclaimer in
        **     the documentation and/or other materials provided with the
        **     distribution.
        **   * Neither the name of The Qt Company Ltd nor the names of its
        **     contributors may be used to endorse or promote products derived
        **     from this software without specific prior written permission.
        **
        **
        ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
        ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
        ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
        ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
        ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
        **
        ** $QT_END_LICENSE$
        **
        ****************************************************************************/
        
        #include <QtWidgets>
        
        #include "mainwindow.h"
        #include "scribblearea.h"
        
        //! [0]
        MainWindow::MainWindow()
        {
            screen = new ScribbleArea;      // create the screen
        
            setCentralWidget(screen);
        
            createActions();
            createMenus();
        
            setWindowTitle(tr("Scribble"));
            resize(800, 480);
        
              secondDisplay = new QWidget;
               secondDisplay->setWindowFlags(Qt::FramelessWindowHint);
               secondDisplay->resize(800,480);
               secondDisplay->show();
        
        
        }
        //! [0]
        
        //! [1]
        void MainWindow::closeEvent(QCloseEvent *event)
        //! [1] //! [2]
        {
            if (maybeSave()) {
                event->accept();
            } else {
                event->ignore();
            }
        }
        //! [2]
        
        //! [3]
        void MainWindow::open()
        //! [3] //! [4]
        {
            if (maybeSave()) {
                QString fileName = QFileDialog::getOpenFileName(this,
                                           tr("Open File"), QDir::currentPath());
                if (!fileName.isEmpty())
                    screen->openImage(fileName);
            }
        }
        //! [4]
        
        //! [5]
        void MainWindow::save()
        //! [5] //! [6]
        {
            QAction *action = qobject_cast<QAction *>(sender());
            QByteArray fileFormat = action->data().toByteArray();
            saveFile(fileFormat);
        }
        //! [6]
        
        //! [7]
        void MainWindow::penColor()
        //! [7] //! [8]
        {
            QColor newColor = QColorDialog::getColor(screen->penColor());
            if (newColor.isValid())
                screen->setPenColor(newColor);
        }
        //! [8]
        
        //! [9]
        void MainWindow::penWidth()
        //! [9] //! [10]
        {
            bool ok;
            int newWidth = QInputDialog::getInt(this, tr("Scribble"),
                                                tr("Select pen width:"),
                                                screen->penWidth(),
                                                1, 50, 1, &ok);
            if (ok)
                screen->setPenWidth(newWidth);
        }
        //! [10]
        
        //! [11]
        void MainWindow::about()
        //! [11] //! [12]
        {
            QMessageBox::about(this, tr("About Scribble"),
                    tr("<p>The <b>Scribble</b> example shows how to use QMainWindow as the "
                       "base widget for an application, and how to reimplement some of "
                       "QWidget's event handlers to receive the events generated for "
                       "the application's widgets:</p><p> We reimplement the mouse event "
                       "handlers to facilitate drawing, the paint event handler to "
                       "update the application and the resize event handler to optimize "
                       "the application's appearance. In addition we reimplement the "
                       "close event handler to intercept the close events before "
                       "terminating the application.</p><p> The example also demonstrates "
                       "how to use QPainter to draw an image in real time, as well as "
                       "to repaint widgets.</p>"));
        
                secondDisplay->update();
        }
        //! [12]
        
        void MainWindow::paintEvent(QPaintEvent *event){
            QPainter painter(secondDisplay);
            painter.drawImage(800,480, screen->updateProjector());
        }
        
        //! [13]
        void MainWindow::createActions()
        //! [13] //! [14]
        {
            openAct = new QAction(tr("&Open..."), this);
            openAct->setShortcuts(QKeySequence::Open);
            connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
        
            foreach (QByteArray format, QImageWriter::supportedImageFormats()) {
                QString text = tr("%1...").arg(QString(format).toUpper());
        
                QAction *action = new QAction(text, this);
                action->setData(format);
                connect(action, SIGNAL(triggered()), this, SLOT(save()));
                saveAsActs.append(action);
            }
        
            printAct = new QAction(tr("&Print..."), this);
            connect(printAct, SIGNAL(triggered()), screen, SLOT(print()));
        
            exitAct = new QAction(tr("E&xit"), this);
            exitAct->setShortcuts(QKeySequence::Quit);
            connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
        
            penColorAct = new QAction(tr("&Pen Color..."), this);
            connect(penColorAct, SIGNAL(triggered()), this, SLOT(penColor()));
        
            penWidthAct = new QAction(tr("Pen &Width..."), this);
            connect(penWidthAct, SIGNAL(triggered()), this, SLOT(penWidth()));
        
            clearScreenAct = new QAction(tr("&Clear Screen"), this);
            clearScreenAct->setShortcut(tr("Ctrl+L"));
            connect(clearScreenAct, SIGNAL(triggered()),
                    screen, SLOT(clearImage()));
        
            aboutAct = new QAction(tr("&About"), this);
            connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
        
            aboutQtAct = new QAction(tr("About &Qt"), this);
            connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
        }
        //! [14]
        
        //! [15]
        void MainWindow::createMenus()
        //! [15] //! [16]
        {
            saveAsMenu = new QMenu(tr("&Save As"), this);
            foreach (QAction *action, saveAsActs)
                saveAsMenu->addAction(action);
        
            fileMenu = new QMenu(tr("&File"), this);
            fileMenu->addAction(openAct);
            fileMenu->addMenu(saveAsMenu);
            fileMenu->addAction(printAct);
            fileMenu->addSeparator();
            fileMenu->addAction(exitAct);
        
            optionMenu = new QMenu(tr("&Options"), this);
            optionMenu->addAction(penColorAct);
            optionMenu->addAction(penWidthAct);
            optionMenu->addSeparator();
            optionMenu->addAction(clearScreenAct);
        
            helpMenu = new QMenu(tr("&Help"), this);
            helpMenu->addAction(aboutAct);
            helpMenu->addAction(aboutQtAct);
        
            menuBar()->addMenu(fileMenu);
            menuBar()->addMenu(optionMenu);
            menuBar()->addMenu(helpMenu);
        }
        //! [16]
        
        //! [17]
        bool MainWindow::maybeSave()
        //! [17] //! [18]
        {
            if (screen->isModified()) {
               QMessageBox::StandardButton ret;
               ret = QMessageBox::warning(this, tr("Scribble"),
                                  tr("The image has been modified.\n"
                                     "Do you want to save your changes?"),
                                  QMessageBox::Save | QMessageBox::Discard
                                  | QMessageBox::Cancel);
                if (ret == QMessageBox::Save) {
                    return saveFile("png");
                } else if (ret == QMessageBox::Cancel) {
                    return false;
                }
            }
            return true;
        }
        //! [18]
        
        //! [19]
        bool MainWindow::saveFile(const QByteArray &fileFormat)
        //! [19] //! [20]
        {
            QString initialPath = QDir::currentPath() + "/untitled." + fileFormat;
        
            QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"),
                                       initialPath,
                                       tr("%1 Files (*.%2);;All Files (*)")
                                       .arg(QString::fromLatin1(fileFormat.toUpper()))
                                       .arg(QString::fromLatin1(fileFormat)));
            if (fileName.isEmpty()) {
                return false;
            } else {
                return screen->saveImage(fileName, fileFormat.constData());
            }
        }
        //! [20]
        
        
        /****************************************************************************
        **
        ** Copyright (C) 2016 The Qt Company Ltd.
        ** Contact: https://www.qt.io/licensing/
        **
        ** This file is part of the examples of the Qt Toolkit.
        **
        ** $QT_BEGIN_LICENSE:BSD$
        ** Commercial License Usage
        ** Licensees holding valid commercial Qt licenses may use this file in
        ** accordance with the commercial license agreement provided with the
        ** Software or, alternatively, in accordance with the terms contained in
        ** a written agreement between you and The Qt Company. For licensing terms
        ** and conditions see https://www.qt.io/terms-conditions. For further
        ** information use the contact form at https://www.qt.io/contact-us.
        **
        ** BSD License Usage
        ** Alternatively, you may use this file under the terms of the BSD license
        ** as follows:
        **
        ** "Redistribution and use in source and binary forms, with or without
        ** modification, are permitted provided that the following conditions are
        ** met:
        **   * Redistributions of source code must retain the above copyright
        **     notice, this list of conditions and the following disclaimer.
        **   * Redistributions in binary form must reproduce the above copyright
        **     notice, this list of conditions and the following disclaimer in
        **     the documentation and/or other materials provided with the
        **     distribution.
        **   * Neither the name of The Qt Company Ltd nor the names of its
        **     contributors may be used to endorse or promote products derived
        **     from this software without specific prior written permission.
        **
        **
        ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
        ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
        ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
        ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
        ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
        ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
        ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
        **
        ** $QT_END_LICENSE$
        **
        ****************************************************************************/
        
        #include <QtWidgets>
        #ifndef QT_NO_PRINTER
        #include <QPrinter>
        #include <QPrintDialog>
        #endif
        
        #include "scribblearea.h"
        #include "mainwindow.h"
        
        //! [0]
        ScribbleArea::ScribbleArea(QWidget *parent)
            : QWidget(parent)
        {
            setAttribute(Qt::WA_StaticContents);
            modified = false;
            scribbling = false;
            myPenWidth = 1;
            myPenColor = Qt::blue;
        
        }
        //! [0]
        
        //! [1]
        bool ScribbleArea::openImage(const QString &fileName)
        //! [1] //! [2]
        {
            QImage loadedImage;
            if (!loadedImage.load(fileName))
                return false;
        
            QSize newSize = loadedImage.size().expandedTo(size());
            resizeImage(&loadedImage, newSize);
            image = loadedImage;
            modified = false;
            update();
            return true;
        }
        //! [2]
        
        //! [3]
        bool ScribbleArea::saveImage(const QString &fileName, const char *fileFormat)
        //! [3] //! [4]
        {
            QImage visibleImage = image;
            resizeImage(&visibleImage, size());
        
            if (visibleImage.save(fileName, fileFormat)) {
                modified = false;
                return true;
            } else {
                return false;
            }
        }
        //! [4]
        //!
        //!
        QImage ScribbleArea::updateProjector(){
            QImage returnImage = image;
            return returnImage;
        }
        
        //! [5]
        void ScribbleArea::setPenColor(const QColor &newColor)
        //! [5] //! [6]
        {
            myPenColor = newColor;
        }
        //! [6]
        
        //! [7]
        void ScribbleArea::setPenWidth(int newWidth)
        //! [7] //! [8]
        {
            myPenWidth = newWidth;
        }
        //! [8]
        
        //! [9]
        void ScribbleArea::clearImage()
        //! [9] //! [10]
        {
            image.fill(qRgb(255, 255, 255));
            modified = true;
            update();
        }
        //! [10]
        
        //! [11]
        void ScribbleArea::mousePressEvent(QMouseEvent *event)
        //! [11] //! [12]
        {
            if (event->button() == Qt::LeftButton) {
                lastPoint = event->pos();
                scribbling = true;
            }
        }
        
        void ScribbleArea::mouseMoveEvent(QMouseEvent *event)
        {
            if ((event->buttons() & Qt::LeftButton) && scribbling)
                drawLineTo(event->pos());
        }
        
        void ScribbleArea::mouseReleaseEvent(QMouseEvent *event)
        {
            if (event->button() == Qt::LeftButton && scribbling) {
                drawLineTo(event->pos());
                scribbling = false;
            }
        }
        
        //! [12] //! [13]
        void ScribbleArea::paintEvent(QPaintEvent *event)
        //! [13] //! [14]
        {
            QPainter painter(this);
            QRect dirtyRect = event->rect();
            painter.drawImage(dirtyRect, image, dirtyRect);
        
         //   QPainter painter2(projector);
         //   QRect dirtyRect2 = event->rect();
         //   painter2.drawImage(dirtyRect, image, dirtyRect);
        }
        //! [14]
        
        //! [15]
        void ScribbleArea::resizeEvent(QResizeEvent *event)
        //! [15] //! [16]
        {
            if (width() > image.width() || height() > image.height()) {
                int newWidth = qMax(width() + 128, image.width());
                int newHeight = qMax(height() + 128, image.height());
                resizeImage(&image, QSize(newWidth, newHeight));
                update();
            }
            QWidget::resizeEvent(event);
        }
        //! [16]
        
        //! [17]
        void ScribbleArea::drawLineTo(const QPoint &endPoint)
        //! [17] //! [18]
        {
            QPainter painter(&image);
            painter.setPen(QPen(myPenColor, myPenWidth, Qt::SolidLine, Qt::RoundCap,
                                Qt::RoundJoin));
            painter.drawLine(lastPoint, endPoint);
            modified = true;
        
            int rad = (myPenWidth / 2) + 2;
            update(QRect(lastPoint, endPoint).normalized()
                                             .adjusted(-rad, -rad, +rad, +rad));
            lastPoint = endPoint;
        }
        //! [18]
        
        //! [19]
        void ScribbleArea::resizeImage(QImage *image, const QSize &newSize)
        //! [19] //! [20]
        {
            if (image->size() == newSize)
                return;
        
            QImage newImage(newSize, QImage::Format_RGB32);
            newImage.fill(qRgb(255, 255, 255));
            QPainter painter(&newImage);
            painter.drawImage(QPoint(0, 0), *image);
            *image = newImage;
        }
        //! [20]
        
        //! [21]
        void ScribbleArea::print()
        {
        #if !defined(QT_NO_PRINTER) && !defined(QT_NO_PRINTDIALOG)
            QPrinter printer(QPrinter::HighResolution);
        
            QPrintDialog printDialog(&printer, this);
        //! [21] //! [22]
            if (printDialog.exec() == QDialog::Accepted) {
                QPainter painter(&printer);
                QRect rect = painter.viewport();
                QSize size = image.size();
                size.scale(rect.size(), Qt::KeepAspectRatio);
                painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
                painter.setWindow(image.rect());
                painter.drawImage(0, 0, image);
            }
        #endif // QT_NO_PRINTER
        }
        //! [22]
        
        
        raven-worxR 1 Reply Last reply
        0
        • supersteveS supersteve

          Thanks for the response, i have attempted what you suggested with not much luck.

          I created a function within the ScribbleArea class that returns the QImage image.

          I then used then used the existing Help menu button (just for testing) to update the Widget but i still get the same error.

          /****************************************************************************
          **
          ** Copyright (C) 2016 The Qt Company Ltd.
          ** Contact: https://www.qt.io/licensing/
          **
          ** This file is part of the examples of the Qt Toolkit.
          **
          ** $QT_BEGIN_LICENSE:BSD$
          ** Commercial License Usage
          ** Licensees holding valid commercial Qt licenses may use this file in
          ** accordance with the commercial license agreement provided with the
          ** Software or, alternatively, in accordance with the terms contained in
          ** a written agreement between you and The Qt Company. For licensing terms
          ** and conditions see https://www.qt.io/terms-conditions. For further
          ** information use the contact form at https://www.qt.io/contact-us.
          **
          ** BSD License Usage
          ** Alternatively, you may use this file under the terms of the BSD license
          ** as follows:
          **
          ** "Redistribution and use in source and binary forms, with or without
          ** modification, are permitted provided that the following conditions are
          ** met:
          **   * Redistributions of source code must retain the above copyright
          **     notice, this list of conditions and the following disclaimer.
          **   * Redistributions in binary form must reproduce the above copyright
          **     notice, this list of conditions and the following disclaimer in
          **     the documentation and/or other materials provided with the
          **     distribution.
          **   * Neither the name of The Qt Company Ltd nor the names of its
          **     contributors may be used to endorse or promote products derived
          **     from this software without specific prior written permission.
          **
          **
          ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
          ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
          ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
          ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
          ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
          ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
          ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
          ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
          ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
          ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
          ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
          **
          ** $QT_END_LICENSE$
          **
          ****************************************************************************/
          
          #include <QtWidgets>
          
          #include "mainwindow.h"
          #include "scribblearea.h"
          
          //! [0]
          MainWindow::MainWindow()
          {
              screen = new ScribbleArea;      // create the screen
          
              setCentralWidget(screen);
          
              createActions();
              createMenus();
          
              setWindowTitle(tr("Scribble"));
              resize(800, 480);
          
                secondDisplay = new QWidget;
                 secondDisplay->setWindowFlags(Qt::FramelessWindowHint);
                 secondDisplay->resize(800,480);
                 secondDisplay->show();
          
          
          }
          //! [0]
          
          //! [1]
          void MainWindow::closeEvent(QCloseEvent *event)
          //! [1] //! [2]
          {
              if (maybeSave()) {
                  event->accept();
              } else {
                  event->ignore();
              }
          }
          //! [2]
          
          //! [3]
          void MainWindow::open()
          //! [3] //! [4]
          {
              if (maybeSave()) {
                  QString fileName = QFileDialog::getOpenFileName(this,
                                             tr("Open File"), QDir::currentPath());
                  if (!fileName.isEmpty())
                      screen->openImage(fileName);
              }
          }
          //! [4]
          
          //! [5]
          void MainWindow::save()
          //! [5] //! [6]
          {
              QAction *action = qobject_cast<QAction *>(sender());
              QByteArray fileFormat = action->data().toByteArray();
              saveFile(fileFormat);
          }
          //! [6]
          
          //! [7]
          void MainWindow::penColor()
          //! [7] //! [8]
          {
              QColor newColor = QColorDialog::getColor(screen->penColor());
              if (newColor.isValid())
                  screen->setPenColor(newColor);
          }
          //! [8]
          
          //! [9]
          void MainWindow::penWidth()
          //! [9] //! [10]
          {
              bool ok;
              int newWidth = QInputDialog::getInt(this, tr("Scribble"),
                                                  tr("Select pen width:"),
                                                  screen->penWidth(),
                                                  1, 50, 1, &ok);
              if (ok)
                  screen->setPenWidth(newWidth);
          }
          //! [10]
          
          //! [11]
          void MainWindow::about()
          //! [11] //! [12]
          {
              QMessageBox::about(this, tr("About Scribble"),
                      tr("<p>The <b>Scribble</b> example shows how to use QMainWindow as the "
                         "base widget for an application, and how to reimplement some of "
                         "QWidget's event handlers to receive the events generated for "
                         "the application's widgets:</p><p> We reimplement the mouse event "
                         "handlers to facilitate drawing, the paint event handler to "
                         "update the application and the resize event handler to optimize "
                         "the application's appearance. In addition we reimplement the "
                         "close event handler to intercept the close events before "
                         "terminating the application.</p><p> The example also demonstrates "
                         "how to use QPainter to draw an image in real time, as well as "
                         "to repaint widgets.</p>"));
          
                  secondDisplay->update();
          }
          //! [12]
          
          void MainWindow::paintEvent(QPaintEvent *event){
              QPainter painter(secondDisplay);
              painter.drawImage(800,480, screen->updateProjector());
          }
          
          //! [13]
          void MainWindow::createActions()
          //! [13] //! [14]
          {
              openAct = new QAction(tr("&Open..."), this);
              openAct->setShortcuts(QKeySequence::Open);
              connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
          
              foreach (QByteArray format, QImageWriter::supportedImageFormats()) {
                  QString text = tr("%1...").arg(QString(format).toUpper());
          
                  QAction *action = new QAction(text, this);
                  action->setData(format);
                  connect(action, SIGNAL(triggered()), this, SLOT(save()));
                  saveAsActs.append(action);
              }
          
              printAct = new QAction(tr("&Print..."), this);
              connect(printAct, SIGNAL(triggered()), screen, SLOT(print()));
          
              exitAct = new QAction(tr("E&xit"), this);
              exitAct->setShortcuts(QKeySequence::Quit);
              connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
          
              penColorAct = new QAction(tr("&Pen Color..."), this);
              connect(penColorAct, SIGNAL(triggered()), this, SLOT(penColor()));
          
              penWidthAct = new QAction(tr("Pen &Width..."), this);
              connect(penWidthAct, SIGNAL(triggered()), this, SLOT(penWidth()));
          
              clearScreenAct = new QAction(tr("&Clear Screen"), this);
              clearScreenAct->setShortcut(tr("Ctrl+L"));
              connect(clearScreenAct, SIGNAL(triggered()),
                      screen, SLOT(clearImage()));
          
              aboutAct = new QAction(tr("&About"), this);
              connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
          
              aboutQtAct = new QAction(tr("About &Qt"), this);
              connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
          }
          //! [14]
          
          //! [15]
          void MainWindow::createMenus()
          //! [15] //! [16]
          {
              saveAsMenu = new QMenu(tr("&Save As"), this);
              foreach (QAction *action, saveAsActs)
                  saveAsMenu->addAction(action);
          
              fileMenu = new QMenu(tr("&File"), this);
              fileMenu->addAction(openAct);
              fileMenu->addMenu(saveAsMenu);
              fileMenu->addAction(printAct);
              fileMenu->addSeparator();
              fileMenu->addAction(exitAct);
          
              optionMenu = new QMenu(tr("&Options"), this);
              optionMenu->addAction(penColorAct);
              optionMenu->addAction(penWidthAct);
              optionMenu->addSeparator();
              optionMenu->addAction(clearScreenAct);
          
              helpMenu = new QMenu(tr("&Help"), this);
              helpMenu->addAction(aboutAct);
              helpMenu->addAction(aboutQtAct);
          
              menuBar()->addMenu(fileMenu);
              menuBar()->addMenu(optionMenu);
              menuBar()->addMenu(helpMenu);
          }
          //! [16]
          
          //! [17]
          bool MainWindow::maybeSave()
          //! [17] //! [18]
          {
              if (screen->isModified()) {
                 QMessageBox::StandardButton ret;
                 ret = QMessageBox::warning(this, tr("Scribble"),
                                    tr("The image has been modified.\n"
                                       "Do you want to save your changes?"),
                                    QMessageBox::Save | QMessageBox::Discard
                                    | QMessageBox::Cancel);
                  if (ret == QMessageBox::Save) {
                      return saveFile("png");
                  } else if (ret == QMessageBox::Cancel) {
                      return false;
                  }
              }
              return true;
          }
          //! [18]
          
          //! [19]
          bool MainWindow::saveFile(const QByteArray &fileFormat)
          //! [19] //! [20]
          {
              QString initialPath = QDir::currentPath() + "/untitled." + fileFormat;
          
              QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"),
                                         initialPath,
                                         tr("%1 Files (*.%2);;All Files (*)")
                                         .arg(QString::fromLatin1(fileFormat.toUpper()))
                                         .arg(QString::fromLatin1(fileFormat)));
              if (fileName.isEmpty()) {
                  return false;
              } else {
                  return screen->saveImage(fileName, fileFormat.constData());
              }
          }
          //! [20]
          
          
          /****************************************************************************
          **
          ** Copyright (C) 2016 The Qt Company Ltd.
          ** Contact: https://www.qt.io/licensing/
          **
          ** This file is part of the examples of the Qt Toolkit.
          **
          ** $QT_BEGIN_LICENSE:BSD$
          ** Commercial License Usage
          ** Licensees holding valid commercial Qt licenses may use this file in
          ** accordance with the commercial license agreement provided with the
          ** Software or, alternatively, in accordance with the terms contained in
          ** a written agreement between you and The Qt Company. For licensing terms
          ** and conditions see https://www.qt.io/terms-conditions. For further
          ** information use the contact form at https://www.qt.io/contact-us.
          **
          ** BSD License Usage
          ** Alternatively, you may use this file under the terms of the BSD license
          ** as follows:
          **
          ** "Redistribution and use in source and binary forms, with or without
          ** modification, are permitted provided that the following conditions are
          ** met:
          **   * Redistributions of source code must retain the above copyright
          **     notice, this list of conditions and the following disclaimer.
          **   * Redistributions in binary form must reproduce the above copyright
          **     notice, this list of conditions and the following disclaimer in
          **     the documentation and/or other materials provided with the
          **     distribution.
          **   * Neither the name of The Qt Company Ltd nor the names of its
          **     contributors may be used to endorse or promote products derived
          **     from this software without specific prior written permission.
          **
          **
          ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
          ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
          ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
          ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
          ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
          ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
          ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
          ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
          ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
          ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
          ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
          **
          ** $QT_END_LICENSE$
          **
          ****************************************************************************/
          
          #include <QtWidgets>
          #ifndef QT_NO_PRINTER
          #include <QPrinter>
          #include <QPrintDialog>
          #endif
          
          #include "scribblearea.h"
          #include "mainwindow.h"
          
          //! [0]
          ScribbleArea::ScribbleArea(QWidget *parent)
              : QWidget(parent)
          {
              setAttribute(Qt::WA_StaticContents);
              modified = false;
              scribbling = false;
              myPenWidth = 1;
              myPenColor = Qt::blue;
          
          }
          //! [0]
          
          //! [1]
          bool ScribbleArea::openImage(const QString &fileName)
          //! [1] //! [2]
          {
              QImage loadedImage;
              if (!loadedImage.load(fileName))
                  return false;
          
              QSize newSize = loadedImage.size().expandedTo(size());
              resizeImage(&loadedImage, newSize);
              image = loadedImage;
              modified = false;
              update();
              return true;
          }
          //! [2]
          
          //! [3]
          bool ScribbleArea::saveImage(const QString &fileName, const char *fileFormat)
          //! [3] //! [4]
          {
              QImage visibleImage = image;
              resizeImage(&visibleImage, size());
          
              if (visibleImage.save(fileName, fileFormat)) {
                  modified = false;
                  return true;
              } else {
                  return false;
              }
          }
          //! [4]
          //!
          //!
          QImage ScribbleArea::updateProjector(){
              QImage returnImage = image;
              return returnImage;
          }
          
          //! [5]
          void ScribbleArea::setPenColor(const QColor &newColor)
          //! [5] //! [6]
          {
              myPenColor = newColor;
          }
          //! [6]
          
          //! [7]
          void ScribbleArea::setPenWidth(int newWidth)
          //! [7] //! [8]
          {
              myPenWidth = newWidth;
          }
          //! [8]
          
          //! [9]
          void ScribbleArea::clearImage()
          //! [9] //! [10]
          {
              image.fill(qRgb(255, 255, 255));
              modified = true;
              update();
          }
          //! [10]
          
          //! [11]
          void ScribbleArea::mousePressEvent(QMouseEvent *event)
          //! [11] //! [12]
          {
              if (event->button() == Qt::LeftButton) {
                  lastPoint = event->pos();
                  scribbling = true;
              }
          }
          
          void ScribbleArea::mouseMoveEvent(QMouseEvent *event)
          {
              if ((event->buttons() & Qt::LeftButton) && scribbling)
                  drawLineTo(event->pos());
          }
          
          void ScribbleArea::mouseReleaseEvent(QMouseEvent *event)
          {
              if (event->button() == Qt::LeftButton && scribbling) {
                  drawLineTo(event->pos());
                  scribbling = false;
              }
          }
          
          //! [12] //! [13]
          void ScribbleArea::paintEvent(QPaintEvent *event)
          //! [13] //! [14]
          {
              QPainter painter(this);
              QRect dirtyRect = event->rect();
              painter.drawImage(dirtyRect, image, dirtyRect);
          
           //   QPainter painter2(projector);
           //   QRect dirtyRect2 = event->rect();
           //   painter2.drawImage(dirtyRect, image, dirtyRect);
          }
          //! [14]
          
          //! [15]
          void ScribbleArea::resizeEvent(QResizeEvent *event)
          //! [15] //! [16]
          {
              if (width() > image.width() || height() > image.height()) {
                  int newWidth = qMax(width() + 128, image.width());
                  int newHeight = qMax(height() + 128, image.height());
                  resizeImage(&image, QSize(newWidth, newHeight));
                  update();
              }
              QWidget::resizeEvent(event);
          }
          //! [16]
          
          //! [17]
          void ScribbleArea::drawLineTo(const QPoint &endPoint)
          //! [17] //! [18]
          {
              QPainter painter(&image);
              painter.setPen(QPen(myPenColor, myPenWidth, Qt::SolidLine, Qt::RoundCap,
                                  Qt::RoundJoin));
              painter.drawLine(lastPoint, endPoint);
              modified = true;
          
              int rad = (myPenWidth / 2) + 2;
              update(QRect(lastPoint, endPoint).normalized()
                                               .adjusted(-rad, -rad, +rad, +rad));
              lastPoint = endPoint;
          }
          //! [18]
          
          //! [19]
          void ScribbleArea::resizeImage(QImage *image, const QSize &newSize)
          //! [19] //! [20]
          {
              if (image->size() == newSize)
                  return;
          
              QImage newImage(newSize, QImage::Format_RGB32);
              newImage.fill(qRgb(255, 255, 255));
              QPainter painter(&newImage);
              painter.drawImage(QPoint(0, 0), *image);
              *image = newImage;
          }
          //! [20]
          
          //! [21]
          void ScribbleArea::print()
          {
          #if !defined(QT_NO_PRINTER) && !defined(QT_NO_PRINTDIALOG)
              QPrinter printer(QPrinter::HighResolution);
          
              QPrintDialog printDialog(&printer, this);
          //! [21] //! [22]
              if (printDialog.exec() == QDialog::Accepted) {
                  QPainter painter(&printer);
                  QRect rect = painter.viewport();
                  QSize size = image.size();
                  size.scale(rect.size(), Qt::KeepAspectRatio);
                  painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
                  painter.setWindow(image.rect());
                  painter.drawImage(0, 0, image);
              }
          #endif // QT_NO_PRINTER
          }
          //! [22]
          
          
          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by raven-worx
          #4

          @supersteve
          because you keep doing the same mistake!

          void MainWindow::paintEvent(QPaintEvent *event){
              QPainter painter(secondDisplay);
              painter.drawImage(800,480, screen->updateProjector());
          }
          

          As i said: A widget is only allowed to paint to itself in it's paintEvent() handler.
          You need a custom class and reimplement the paintEvnet() handler and do the painting there. Or you simply use a QLabel and set a pixmap on it.

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • supersteveS Offline
            supersteveS Offline
            supersteve
            wrote on last edited by
            #5

            Thanks for your help, using your advice i used QLabel and converted the first screen to pixmap and now i can get the image on my second screen.

            1 Reply Last reply
            0

            • Login

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