Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 如何在每次需要重新绘制时在pixmap中获取qwidget/渲染它?_Qt - Fatal编程技术网

Qt 如何在每次需要重新绘制时在pixmap中获取qwidget/渲染它?

Qt 如何在每次需要重新绘制时在pixmap中获取qwidget/渲染它?,qt,Qt,我有一个QWidget,我不想在屏幕上显示。相反,我希望每次重新绘制小部件时都能得到它的pixmap,以便将它发送到我正在处理的应用程序的另一部分。API提供了两种方法:和 问题是这两种方法都将触发小部件的新paintEvent,创建小部件的递归重新绘制,因此它们不应在paintEvent方法中使用 那么,我怎样才能在每次重新绘制小部件时得到一个代表它的pixmap呢 我找到了一个解决办法。我把我想要抓取的小部件的所有内容都放在一个框架内。然后我抓住了镜框。它不是很优雅,但很管用。另一种方法-您

我有一个QWidget,我不想在屏幕上显示。相反,我希望每次重新绘制小部件时都能得到它的pixmap,以便将它发送到我正在处理的应用程序的另一部分。API提供了两种方法:和

问题是这两种方法都将触发小部件的新
paintEvent
,创建小部件的递归重新绘制,因此它们不应在
paintEvent
方法中使用


那么,我怎样才能在每次重新绘制小部件时得到一个代表它的pixmap呢

我找到了一个解决办法。我把我想要抓取的小部件的所有内容都放在一个框架内。然后我抓住了镜框。它不是很优雅,但很管用。

另一种方法-您可以进行下一步检查:

void paintEvent(QPaintEvent*)
{
  QPainter painter(this);
  // If painter redirection was turned on, the painter will *not* paint on `this`!
  // Painting code
  //...
  if ( this == qobject_cast< QWidget * >( painter.device() ) )
  {
    // Do grabbing
  }
}
void paintEvent(QPaintEvent*)
{
油漆工(本);
//如果启用了画家重定向,画家将*不*在“this”上绘画!
//绘画代码
//...
if(this==qobject\u cast(painter.device())
{
//抓取
}
}

paintEvent在小部件上绘制和抓取时都被调用
painter->device()
将返回非空值,但仅当当前绘制在小部件上时,
QWidget*
对象的实例才会返回。如果在
QPixmap
上绘图,它将返回
QPixmap*
。因此,只有在真正的小部件上执行绘制时,才需要调用抓取代码。

我知道这个问题很老,但我想对解决方案进行澄清,发布一些实际的工作代码以供将来参考

sourceWidget是我们想要呈现的小部件(也称为将内容捕获为图像)

sourceFrame是sourceWidget的父级

renderLabel是我们要在其中呈现sourceWidget的目标

这是h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFrame>
#include <QLabel>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MyEventFilter : public QObject {

Q_OBJECT

public:
    MyEventFilter(QObject* parent = nullptr);

protected:
    bool eventFilter(QObject* obj, QEvent* event) override;
};

class MainWindow : public QMainWindow {

    Q_OBJECT

public:
    MainWindow(QWidget* parent = nullptr);
    ~MainWindow();

     QFrame* sourceFrame;
     QWidget* sourceWidget;
     QLabel* renderLabel;

private:
    Ui::MainWindow* ui;

    MyEventFilter* myEventFilter;
};
#endif // MAINWINDOW_H
\ifndef主窗口
#定义主窗口
#包括
#包括
#包括
QT_开始名称空间
命名空间Ui{class MainWindow;}
QT_END_名称空间
MyEventFilter类:公共QObject{
Q_对象
公众:
MyEventFilter(QObject*parent=nullptr);
受保护的:
布尔事件过滤器(QObject*obj,QEvent*event)覆盖;
};
类主窗口:公共QMainWindow{
Q_对象
公众:
主窗口(QWidget*parent=nullptr);
~main窗口();
QFrame*源帧;
QWidget*sourceWidget;
QLabel*渲染标签;
私人:
Ui::MainWindow*Ui;
MyEventFilter*MyEventFilter;
};
#endif//main窗口
这是.cpp

#include "MainWindow.h"
#include "ui_MainWindow.h"

#include <QDebug>
#include <QPaintEvent>

MyEventFilter::MyEventFilter(QObject *parent) : QObject(parent) {

     Q_UNUSED(parent);
}

bool MyEventFilter::eventFilter(QObject* obj, QEvent* event) {

    if (event->type() == QEvent::Paint) {
        QPaintEvent* paintEvent = static_cast<QPaintEvent*>(event);
        qDebug() << "Paint Event on" << obj << parent();

        if (qobject_cast<MainWindow*>(parent())) {
        //QImage image = qobject_cast<MainWindow*>(parent())->sourceWidget->grab().toImage();
        QPixmap pixmap = qobject_cast<MainWindow*>(parent())->sourceWidget->grab();
        qobject_cast<MainWindow*>(parent())->renderLabel->setPixmap(pixmap);
    }

    Q_UNUSED(paintEvent);
    return true;

} else {

        // standard event processing
        return QObject::eventFilter(obj, event);
    }
}

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {

    ui->setupUi(this);

    sourceFrame = ui->sourceFrame;
    sourceWidget = ui->sourceWidget;
    renderLabel = ui->renderLabel;

    myEventFilter = nullptr;
    myEventFilter = new MyEventFilter(this);
    sourceFrame->installEventFilter(myEventFilter);
}

MainWindow::~MainWindow() {

    delete ui;
}
#包括“MainWindow.h”
#包括“ui_main window.h”
#包括
#包括
MyEventFilter::MyEventFilter(QObject*父对象):QObject(父对象){
Q_未使用(父母);
}
bool MyEventFilter::eventFilter(QObject*obj,QEvent*event){
如果(事件->类型()==QEvent::Paint){
QPaintEvent*paintEvent=静态施法(事件);
qDebug()sourceWidget->grab();
qobject_cast(parent())->renderLabel->setPixmap(pixmap);
}
Q_未使用(油漆事件);
返回true;
}否则{
//标准事件处理
返回QObject::eventFilter(对象,事件);
}
}
MainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(新ui::MainWindow){
用户界面->设置用户界面(此);
sourceFrame=ui->sourceFrame;
sourceWidget=ui->sourceWidget;
renderLabel=ui->renderLabel;
myEventFilter=nullptr;
myEventFilter=新的myEventFilter(此);
sourceFrame->installEventFilter(myEventFilter);
}
MainWindow::~MainWindow(){
删除用户界面;
}

好的,很抱歉英语不好。好的,但是小部件的paintEvent方法中的painter来自哪里?@DmitrySazonov:这是错误的。必须在
paintEvent
的实现中本地创建画师。这个技巧是使用@DmitrySazonov完成的。@DmitrySazonov:在Qt 5上,内部使用绘制引擎重定向。谢谢,但是动态转换对我来说从来都不起作用,调试器告诉我我的小部件(这个)有一个地址,比如0x84568456,而painter.device()有一个地址0x84568458!