【问题标题】:Qt cannot save pixmapQt 无法保存像素图
【发布时间】:2018-03-16 17:00:59
【问题描述】:

你好我有一个奇怪的问题来保存像素图。

我的小部件标题

public:
  QPixmap *base;  //Base Poses
  QPixmap *Hair;  //Hair
  QPixmap *Composited;  //Final Composition

  bool compisition = false;

  void Composite();

我的小部件 Cpp

在绘画活动中

 base = &pic;
    Hair = &hairs;

    if(compisition)
    {
        QPixmap pix(128,192);
        QPainter *p = new QPainter(&pix);

        p->drawPixmap(0,0,128,192,*base);
        p->drawPixmap(0,0,128,192,*Hair);

        Composited = &pix;
        compisition = false;
    }
void AnimPreview::Composite()
{
    compisition = true;
    this->update();


}

在主窗体源

void MainWindow::on_commandLinkButton_clicked()
{
    QString file = QFileDialog::getSaveFileName(this,
                                               tr("Save Sprite file"),
                                               "",tr("File PNG (*.png)"));

    const QPixmap *pix = ui->SpriteFront->pixmap();

    if(!file.isEmpty())
    {
        QFile files(file);
        files.open(QIODevice::WriteOnly);

        ui->SpriteFront->Composite();
        ui->SpriteFront->Composited->save(&files,"PNG");
    }
}

当我尝试保存文件时,该过程有效,但出现错误

未处理的 win32 异常

更多信息 完整代码在这里

https://pastebin.com/GtaVCXGf

【问题讨论】:

    标签: c++ qt qt5 qpixmap


    【解决方案1】:

    我避免查看可能产生错误的位置,因为问题的可能来源有很多,其中包括:

    • 没有必要创建QPixmap 指针,因为最终您需要将其从内存中清除。

    • QPainter 也会发生同样的情况,因为它只需要是一个局部变量,此外绘制不会立即完成,为了确保它被绘制,你必须调用它的 end() 方法。

    • paintEvent 是一种受保护的方法,因此在设计上我们希望它保持不变。

    • 保存图片不必使用QFile,直接传文件名即可。

    综合以上所有,我们得到以下结果:

    *.h

    #ifndef ANIMPREVIEW_H
    #define ANIMPREVIEW_H
    
    #include <QLabel>
    #include <QPixmap>
    
    class AnimPreview : public QLabel
    {
    public:
        AnimPreview(QWidget *parent = 0);
    
        void Rotate(int value);
        void Composite();
        void Create(int _sex, int _hair);
        QPixmap Composited;
    
    private:
        int sex = 0;
        int hair = 0;
        bool draw = true;
    
        int rotation = 0;
        const int offsetX = 16;
        const int offsetY = 32;
    
        QPixmap base;
        QPixmap Hair;
        bool compisition = false;
    
    protected:
        void paintEvent(QPaintEvent *);
    };
    
    #endif // ANIMPREVIEW_H
    

    *.cpp

    #include "animpreview.h"
    
    #include <QPainter>
    
    AnimPreview::AnimPreview(QWidget *parent):QLabel(parent)
    {
    }
    
    void AnimPreview::paintEvent(QPaintEvent *){
    
        QPainter p(this);
        QPixmap pic;
        QPixmap hairs;
    
        if(draw)
        {
            //Sesso
            switch(sex)
            {
            case 0:
                pic.load(":/Male/Base/Res/man_f.png");
                break;
            case 1:
                pic.load(":/Male/Base/Res/woman_f.png");
    
                break;
            }
    
            //capelli
            if(sex == 1)
            {
                switch(hair)
                {
                case 1:
                    hairs.load(":/Female/Hair/Res/7_aqua.png");
                    break;
                case 2:
                    hairs.load(":/Female/Hair/Res/5_gold.png");
                    break;
                }
            }
    
            if(sex == 0)
            {
                switch (hair)
                {
                case 0:
                    break;
                case 1:
                    hairs.load(":/Male/Hair/Res/1_aqua.png");
                    break;
                case 2:
                    hairs.load(":/Male/Hair/Res/14_black.png");
                    break;
                }
            }
    
        }
    
        p.drawPixmap(width()/2 - offsetX,height()/2 - offsetY,pic,0,rotation,32,48);
        p.drawPixmap(width()/2 - offsetX,height()/2 - offsetY,hairs,0,rotation,32,48);
        p.drawRect(0,0, width()-1, height()-1);
    
        base = pic;
        Hair = hairs;
    
        if(compisition)
        {
            QPixmap pix(128,192);
            QPainter p(&pix);
    
            p.drawPixmap(0,0,128,192, base);
            p.drawPixmap(0,0,128,192, Hair);
    
            p.end();
    
            Composited = pix;
            compisition = false;
        }
    }
    
    void AnimPreview::Rotate(int value)
    {
        rotation = value;
        update();
    }
    
    void AnimPreview::Create(int _sex, int _hair)
    {
        sex = _sex;
        hair = _hair;
        draw = true;
    }
    
    void AnimPreview::Composite()
    {
        compisition = true;
        update();
    }
    

    void MainWindow::on_commandLinkButton_clicked()
    {
        QString file = QFileDialog::getSaveFileName(this,
                                                    tr("Save Sprite file"),
                                                    "",tr("File PNG (*.png)"));
    
        if(!file.isEmpty())
        {
            ui->SpriteFront->Composite();
            ui->SpriteFront->Composited.save(file,"PNG");
        }
    }
    

    【讨论】:

    • paintEvent 中进行除绘画之外的任何操作都是一个 UX 错误。当设置sexhairs 时,可以按需加载像素图——它们可以在工作线程上异步加载,以免阻塞gui。然后,一旦图片可用,worker 发出信号,它被设置在小部件上,因此小部件被更新并最终绘制一切准备就绪。另请注意,使用默认后端,QImageQPixmap 的往返非常便宜,因为像素图只是内部QImage 的薄包装。
    • @KubaOber 你说的完全正确,我看的是其他错误,而不是在应用程序的设计中。稍后我会更新它。谢谢。
    • 您好@eyllanesc,您的代码可以正常工作。但像素图没有保存。 Screen1°s14.postimg.org/g88yt90ht/cattura.png,Screen2°s14.postimg.org/ueopom8tt/cattura.png,图像为空。为了什么?
    猜你喜欢
    • 1970-01-01
    • 2016-05-19
    • 2021-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-15
    • 1970-01-01
    • 2017-02-05
    相关资源
    最近更新 更多