LINUX.ORG.RU

Как отвязать QPixmap от Pixmap'а?

 , ,


0

2

Есть метод, который возвращает QPixmap

QPixmap getPixmap(){
    //...
    XRenderComposite (display, PictOpSrc, picture, None, pixmap, 0,0, 0,0, 0,0, width, height);
    QPixmap qpxmp = QPixmap::fromX11Pixmap(pixmap);
    //...
    return qpxmp;
}

Результат сетаю в вижет и хочу отрисовать в качестве фона.

int main(){
    //...
    QPixmap p = getPixmap();
    MyWidget* wdg = new MyWidget;
    wdg->show();
    wdg->setPixmap(&p);
    //...
}
//...
class MyWidget : public QWidget {
    Q_OBJECT
private:
     QPixmap* image = NULL;
public:
    explicit MyWidget(QWidget *parent = 0) : QWidget(parent) {
         QTimer::singleShot(0, this, SLOT(run()));
    }
    ~MyWidget(){}
    void paintEvent(QPaintEvent* evt){
        if (image){
            QPainter painter(this);
            QRect geo = this->geometry();
            painter.drawPixmap(0, 0, image->scaled(geo.size()));
        }
    }
    void setPixmap(QPixmap* image){
        this->image = image;
    }
};

В таком виде приложение падает на том основании, что у переменной image внутри фигня: валится на isNull методе QPixmap. Пытался использовать QPixmapCache, результат практически тот же. А вот если перед вызовом setPixmap перегнать исходный QPixmap в QByteArray то всё работает, но сама операция QPixmap -> QByteArray -> QImage сильно жрёт процессор.

Я в общих чертах понимаю, почему это происходит, но совершенно не понимаю что с этим можно сделать. Как мне быстро и без оверхеда закешировать QPixmap в MyWidget?

★★★★★

void setPixmap(QPixmap* image)

для начала избавься от указателя

QPixmap class uses implicit data sharing

dib2 ★★★★★
()

Плюсую предыдущего оратора. Избавься от указателей на QPixmap. Есть подозрение, что QPixmap p в main банально помирает до его использования в отрисовке.

Второй момент - проверь время жизни X11 pixmap. Судя по документации, он используется напрямую в QPixmap, без копирования данных. Следовательно, его нельзя убивать раньше, чем созданный из него QPixmap.

archie
()

Делай так:

QPixmap getPixmap(){
    //...
    XRenderComposite (display, PictOpSrc, picture, None, pixmap, 0,0, 0,0, 0,0, width, height);
    QPixmap qpxmp = QPixmap::fromX11Pixmap(pixmap);
    //...
    return qpxmp.copy(); // !! deep copy !!
}

Потому что ты убиваешь данные при выходе из функции. А с copy - нет.

grondek
()
Ответ на: комментарий от grondek

Дело не в этом указателе

один хер так делать не надо. совсем.

dib2 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.