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