Stanislaw T
Stanislaw T

Reputation: 420

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);
}

Upvotes: 1

Views: 1694

Answers (3)

ManuelH
ManuelH

Reputation: 866

When you are constructing the filename and its path as follows:

QString fileName = initialPath + date;

You will have a path similar to

C:/Users/YourName/Pictures

for your initial path.

While your date will be in the format of

Sun Sep 7 11:35:46 2014

So during your concatenation, you would end up with something like

C:/Users/YourName/PicturesSun Sep 7 11:35:46 2014

If you look closely, there are quite a few problems here:

  1. You are missing an "/" at the end of your initial path
  2. Your date String contains characters that Windows does not allow for file names
  3. Once saved, the file will be missing its extension, this will need to be added to the end of your filename String as well.

Fixes required:

You need change the date format to something acceptable for Windows by using

QString date = local.toString("A Valid QDateTime format here for windows")

QString fileName = initialPath + "/" + date + "." + format;

Upvotes: 1

isamert
isamert

Reputation: 492

It just works under linux. In addition to @Chernobyl's answer, AFAIK QPixmap::save doesn't add the suffix automatically, so you need to change

QString fileName = initialPath + date;

to

QString fileName = initialPath + date.replace(":", "-") + ".png";

(The .replace(":", "-") part is for escaping forbidden ":" symbol in the file name)

Upvotes: 2

Jablonski
Jablonski

Reputation: 18504

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.

Upvotes: 2

Related Questions