Search code examples
c++qtqpixmap

qt pixmap.save not working


In my screenshot taking project the QPixmap.save() function returns false meaning fails every time. However when I copy the example project from Qt page http://qt-project.org/doc/qt-5/qtwidgets-desktop-screenshot-example.html, it works. Thus it rules out Windows 7 issue with file permissions.

So I wonder why it fails?

widget.h file:

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void updateTimer();
    void startScreenshots();
    void stopScreenshots();
    void takeScreenshot();
private:
    Ui::Widget *ui;


    QString initialPath;
    QPixmap currentScreenshot;
    QSpinBox * delaySpinBox;
    QPushButton * startButton;
    QPushButton * stopButton;
    QHBoxLayout * hboxLayout;
    QGroupBox * groupBox;
    QTimer * timer;
    void setInitialPath();
    void addStuff();
};

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    setInitialPath();

    addStuff();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::updateTimer()
{
    timer->stop();
    int milisecs = delaySpinBox->value() *1000;
    timer->start( milisecs );
}

void Widget::startScreenshots()
{
    timer->start( delaySpinBox->value() * 1000 );
}

void Widget::stopScreenshots()
{
    timer->stop();
}

void Widget::takeScreenshot()
{
    //take screenshot
    currentScreenshot = QPixmap::grabWindow(QApplication::desktop()->winId());

    //save screenshot
    QString format = "png";

    QDateTime local( QDateTime::currentDateTime() );
    QString date = local.toString();
    QString fileName = initialPath + date;

    if(!currentScreenshot.save(fileName, format.toLatin1().constData()) )
    {
        qDebug() << "didnt save\n";
        QMessageBox::information(this,"failed to save","failed to save");
    }
}

void Widget::setInitialPath()
{
    initialPath = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
      "/home",
      QFileDialog::ShowDirsOnly
       | QFileDialog::DontResolveSymlinks);
}

void Widget::addStuff()
{
  timer = new QTimer(this);
  connect(timer,SIGNAL(timeout()),this,SLOT(takeScreenshot()) );

  delaySpinBox = new QSpinBox(this);
  delaySpinBox->setValue(60);
  delaySpinBox->setSuffix(tr(" s"));
  connect( delaySpinBox,SIGNAL(valueChanged(int)),this,SLOT(updateTimer()) );

  startButton = new QPushButton(this);
  startButton->setText("start");
  connect(startButton,SIGNAL(clicked()),this,SLOT(startScreenshots()) );

  stopButton = new QPushButton(this);
  stopButton->setText("stop");
  connect(stopButton,SIGNAL(clicked()),this,SLOT(stopScreenshots()) );

  hboxLayout = new QHBoxLayout(this);
  hboxLayout->addWidget(startButton);
  hboxLayout->addWidget(stopButton);
  hboxLayout->addWidget(delaySpinBox);

  groupBox = new QGroupBox(tr("Options"));
  groupBox->setLayout(hboxLayout);

  setLayout(hboxLayout);
}

Solution

  • QDateTime local( QDateTime::currentDateTime() ) 
    

    probably contains symbols which Windows doesn't allow. (there are few symbols). That's why you cannot save it.

    Solution: fist of all, try to remove dateTime from filename and see is it work. If you want use dateTime try format it without forbidden symbols

    Forbidden symbols in Windows for example:

    < (less than)
    > (greater than)
    : (colon)
    " (double quote)
    / (forward slash)
    \ (backslash)
    | (vertical bar or pipe)
    ? (question mark)
    * (asterisk)
    

    QDateTime always return string which contains colon, but it is forbidden and you can't use it, you should replace it.