[英]Qt subclassed QStyledItemDelegate paint method is never called
[英]Paint method of QQuickPaintedItem not called
我有一個要在QML中實例化的C ++ QQuickPaintedItem。 但是,從來不會調用paint()方法。
這是我的代碼:
CPlotXY.h
#ifndef CPLOTXY_H
#define CPLOTXY_H
#include <QQuickPaintedItem>
#include <lib/qcustomplot-source/qcustomplot.h>
#include <QQuickView>
class CPlotXY : public QQuickPaintedItem
{
Q_OBJECT
public:
CPlotXY(QQuickItem* parent = 0);
virtual ~CPlotXY();
void paint(QPainter* painter);
Q_INVOKABLE void init();
protected:
void routeMouseEvents( QMouseEvent* event );
virtual void mousePressEvent( QMouseEvent* event );
virtual void mouseReleaseEvent( QMouseEvent* event );
virtual void mouseMoveEvent( QMouseEvent* event );
virtual void mouseDoubleClickEvent( QMouseEvent* event );
void setupQuadraticDemo( QCustomPlot* Q_CustomPlot );
private:
QCustomPlot* Q_CustomPlot;
private slots:
void graphClicked( QCPAbstractPlottable* plottable );
void onCustomReplot();
void updateCustomPlotSize();
};
#endif // CPLOTXY_H
CPlotXY.cpp
#include "CPlotXY.h"
CPlotXY::CPlotXY( QQuickItem* parent ) : QQuickPaintedItem( parent ), Q_CustomPlot( nullptr )
{
setFlag( QQuickItem::ItemHasContents, true );
setAcceptedMouseButtons( Qt::AllButtons );
connect( this, &QQuickPaintedItem::widthChanged, this, &CPlotXY::updateCustomPlotSize );
connect( this, &QQuickPaintedItem::heightChanged, this, &CPlotXY::updateCustomPlotSize );
}
CPlotXY::~CPlotXY()
{
delete Q_CustomPlot;
Q_CustomPlot = nullptr;
}
void CPlotXY::init()
{
Q_CustomPlot = new QCustomPlot();
updateCustomPlotSize();
setupQuadraticDemo( Q_CustomPlot );
connect( Q_CustomPlot, &QCustomPlot::afterReplot, this, &CPlotXY::onCustomReplot );
Q_CustomPlot->replot();
}
void CPlotXY::paint(QPainter* painter)
{
qDebug() << "@####";
if (Q_CustomPlot)
{
QPixmap Q_PixMap( boundingRect().size().toSize() );
QCPPainter Q_CPPainter( &Q_PixMap );
Q_CustomPlot->toPainter(&Q_CPPainter);
painter->drawPixmap(QPoint(), Q_PixMap);
}
}
void CPlotXY::mousePressEvent( QMouseEvent* Q_Event )
{
qDebug() << Q_FUNC_INFO;
routeMouseEvents( Q_Event );
}
void CPlotXY::mouseReleaseEvent( QMouseEvent* Q_Event )
{
qDebug() << Q_FUNC_INFO;
routeMouseEvents( Q_Event );
}
void CPlotXY::mouseMoveEvent( QMouseEvent* Q_Event )
{
routeMouseEvents( Q_Event );
}
void CPlotXY::mouseDoubleClickEvent( QMouseEvent* Q_Event )
{
qDebug() << Q_FUNC_INFO;
routeMouseEvents( Q_Event );
}
void CPlotXY::graphClicked( QCPAbstractPlottable* Q_Plottable )
{
qDebug() << Q_FUNC_INFO << QString( "Clicked on graph '%1 " ).arg( Q_Plottable->name() );
}
void CPlotXY::routeMouseEvents( QMouseEvent* Q_Event )
{
if (Q_CustomPlot)
{
QMouseEvent* Q_NewEvent = new QMouseEvent( Q_Event->type(), Q_Event->localPos(), Q_Event->button(), Q_Event->buttons(), Q_Event->modifiers() );
//QCoreApplication::sendEvent( m_CustomPlot, newEvent );
QCoreApplication::postEvent( Q_CustomPlot, Q_NewEvent );
}
}
void CPlotXY::updateCustomPlotSize()
{
if (Q_CustomPlot)
{
Q_CustomPlot->setGeometry( 0, 0, width(), height() );
}
}
void CPlotXY::onCustomReplot()
{
qDebug() << Q_FUNC_INFO;
update();
}
void CPlotXY::setupQuadraticDemo( QCustomPlot* customPlot )
{
// make top right axes clones of bottom left axes:
QCPAxisRect* axisRect = customPlot->axisRect();
// generate some data:
QVector<double> x( 101 ), y( 101 ); // initialize with entries 0..100
QVector<double> lx( 101 ), ly( 101 ); // initialize with entries 0..100
for (int i = 0; i < 101; ++i)
{
x[i] = i / 50.0 - 1; // x goes from -1 to 1
y[i] = x[i] * x[i]; // let's plot a quadratic function
lx[i] = i / 50.0 - 1; //
ly[i] = lx[i]; // linear
}
// create graph and assign data to it:
customPlot->addGraph();
customPlot->graph( 0 )->setPen( QPen( Qt::red ) );
//customPlot->graph( 0 )->setSelectedPen( QPen( Qt::blue, 2 ) );
customPlot->graph( 0 )->setData( x, y );
customPlot->addGraph();
customPlot->graph( 1 )->setPen( QPen( Qt::magenta ) );
//customPlot->graph( 1 )->setSelectedPen( QPen( Qt::blue, 2 ) );
customPlot->graph( 1 )->setData( lx, ly );
// give the axes some labels:
customPlot->xAxis->setLabel( "x" );
customPlot->yAxis->setLabel( "y" );
// set axes ranges, so we see all data:
customPlot->xAxis->setRange( -1, 1 );
customPlot->yAxis->setRange( -1, 1 );
customPlot ->setInteractions( QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables );
connect( customPlot, SIGNAL( plottableClick( QCPAbstractPlottable*, QMouseEvent* ) ), this, SLOT( graphClicked( QCPAbstractPlottable* ) ) );
}
XPlotXY.qml
import QtQuick 2.0
import CPlotXY 1.0
Item {
CPlotXY {
id: customPlot
anchors.fill: parent
Component.onCompleted: init()
}
}
最后,這是我實例化的時候:
Repeater {
id: widgetRepeater
model: pageModel
anchors.fill: parent
delegate: Loader {
property int modelX: model.XPos
property int modelY: model.YPos
//property int modelWidth: model.width
//property int modelHeight: model.height
active: true;
asynchronous: true
//anchors.centerIn: parent
source: "%1.qml".arg(model.Type)
}
}
調用CPlotXY的init()函數並創建對象,但從不調用paint()方法。 我知道解決方案很明顯,但是我對QQuickPaintedItem不滿意。
感謝您的幫助。
我認為這個最小的示例將重現您的問題:
// mypainteditem.h
#ifndef MYPAINTEDITEM_H
#define MYPAINTEDITEM_H
#include <QObject>
#include <QQuickPaintedItem>
class MyPaintedItem : public QQuickPaintedItem
{
Q_OBJECT
public:
MyPaintedItem(QQuickItem* parent = nullptr);
void paint(QPainter* painter);
};
#endif // MYPAINTEDITEM_H
// mypainteditem.cpp
#include "mypainteditem.h"
#include <QDebug>
MyPaintedItem::MyPaintedItem(QQuickItem* parent)
: QQuickPaintedItem(parent)
{
}
void MyPaintedItem::paint(QPainter *painter)
{
qDebug() << "Paint called";
}
// main.qml(將MyPaintedItem
注冊為PaintItem
)
import QtQuick 2.7
import QtQuick.Window 2.1
import PaintItem 1.0
Window {
id:rootWindow
visible: true
width: 800
height: 600
title: qsTr("Test")
PaintItem {
}
}
如您所見:不會調用paint
-method。 問題是:我們沒有PaintItem
大小,因此它是不可見的。 為了避免不必要的paint
呼叫,我們不稱之為。
更改大小將產生繪畫效果:
import QtQuick 2.7
import QtQuick.Window 2.1
import PaintItem 1.0
Window {
id:rootWindow
visible: true
width: 800
height: 600
title: qsTr("Test")
PaintItem {
id: pi
height: width
}
Timer {
interval: 2000 // Set some dimensions after 2 seconds will produce the paint call.
onTriggered: pi.width = 100;
running: true
}
}
如果可能出現問題,為什么您的圖表大小為0
...
在您的文件XPlotXY.qml
您(出於某些原因)將繪圖包裝在一個Item
使該繪圖填充該Item
在main.qml
,創建一個填充窗口的Repeater
。 但是, Repeater
不會調整其委托的大小。 它僅實例化它們。
Repeater
的delegate
是Loader
。 如果未設置顯式大小,則Loader
根據其內容調整其大小。 那么它加載了什么呢? 可能您的XPlotXY.qml
沒有設置大小。 因此, Loader
和繪圖的大小最終為0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.