【问题标题】:qt pixmap.save not workingqt pixmap.save 不工作
【发布时间】:2014-09-07 09:10:25
【问题描述】:

在我的截屏项目中,QPixmap.save() 函数每次都返回错误,意思是失败。但是,当我从 Qt 页面http://qt-project.org/doc/qt-5/qtwidgets-desktop-screenshot-example.html 复制示例项目时,它可以工作。因此它排除了 Windows 7 的文件权限问题。

所以我想知道为什么它会失败?

widget.h 文件:

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

【问题讨论】:

    标签: c++ qt qpixmap


    【解决方案1】:
    QDateTime local( QDateTime::currentDateTime() ) 
    

    可能包含 Windows 不允许的符号。 (符号很少)。这就是你无法保存它的原因。

    解决方案:首先,尝试从文件名中删除 dateTime 并查看它是否有效。 如果你想使用 dateTime 尝试格式化它而不使用禁止符号

    例如 Windows 中的禁止符号:

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

    QDateTime总是返回包含冒号的字符串,但是禁止使用,不能使用,应该替换掉。

    【讨论】:

      【解决方案2】:

      它只在 linux 下工作。除了@Chernobyl 的回答,AFAIK QPixmap::save 不会自动添加后缀,所以你需要更改

      QString fileName = initialPath + date;
      

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

      .replace(":", "-")部分用于转义文件名中禁止的“:”符号)

      【讨论】:

        【解决方案3】:

        当你如下构造文件名及其路径时:

        QString fileName = initialPath + date;
        

        你会有类似的路径

        C:/Users/YourName/Pictures

        为您的初始路径。

        而您的日期格式为

        2014 年 9 月 7 日星期日 11:35:46

        所以在你的连接过程中,你最终会得到类似的东西

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

        如果仔细看,这里有不少问题:

        1. 您在初始路径的末尾缺少一个“/”
        2. 您的日期字符串包含 Windows 不允许用于文件名的字符
        3. 保存后,文件将缺少扩展名,这也需要添加到文件名字符串的末尾。

        需要修复:

        您需要通过使用将日期格式更改为 Windows 可接受的格式

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

        QString 文件名 = 初始路径 + "/" + 日期 + "." + 格式;

        【讨论】:

          猜你喜欢
          • 2018-09-23
          • 2016-04-14
          • 1970-01-01
          • 2018-10-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多