Is there a way to animate a LineSeries with a gradient along the path?
I only found options to animate it statically by replacing the lineseries coloring brush with one that has a gradient for some fixed value. I could set the gradient now everytime a new point is added. But then the gradient would still be only along the y axis. Is there a way to color it along the path.
For example by setting a callback in between the paint function that takes each XYPoint and uses the value to compute a color value using a QVariantAnimation? I'm lacking the experience with QML to know whether or how to approach this, should I subclass something in Python and register a type or how is this customization best approached?
Related
I am looking for a way to apply a horizontal opacity gradient when painting QLine elements using QPainter. Put simply, I want to be able to have the line opacity decrease the further away from the line center it is being painted. The effect I want to achieve corresponds to what a lot of image editing tools comonly describe as hardness of a brush.
Here is a sample image that compares a line using a hard brush to a soft one:
This would be a minimum example for painting a regular QLine:
QPainter p;
p.setPen(QPen(Qt::black, 12, Qt::SolidLine, Qt::RoundCap));
p.drawLine(QPointF(0,0), QPointF(1024,1024));
How and where would I configure the line hardness I am describing? Is there something like a fall-off property when painting QLine elements?
In the docs I could only find examples for how to apply linear gradients between set points, which is not what I am looking for.
That's not QPen painting, that's brush painting, like in say photoshop, and Qt doesn't really support such functionality out of the box.
But it is quite easy to implement, you need a brush stencil pixmap, and you simply draw that pixmap on your target paint device along a line at a given step.
The line interpolation part is already answered here.
It is recommended that the brush stencil is an 8 bit grayscale QImage, then you can easily get a colorized version of that by using the greyscale value as an alpha value for the solid color of choice. QImage is preferable, as it offers individual pixel access. This allows to have any type of brush aside from hard and soft, including certain artistic brushes.
Naturally, if all you need is a soft brush, you can generate that directly in the desired color by utilizing Qt's existing gradients and skip the stencil colorizing part. You can use QPainter to procedurally draw colorizable or full color stencils to use as a brush.
I'm using Qt3D with a combination of this offscreen renderer and modified the framegraph to include a background image, like here.
Unfortunately, adding transparency to the objects drawn over the background image using QPhongAlphaMaterial only works unsatisfactorily.
This is th result:
What you can't see here is that the whole circle part is actually transparent, i.e. the renderer wrote the transparency value of the object for the whole pixel instead of adding it transparently on top of the background.
This is what the rendered object looks like wihtout transparency:
And this is the background:
The framegraph has two branches: one for the backgroun image, which is processed first, and one for the objects. I added a QRenderStateSet for the objects that contains a QBlendEquation with the blend function set to add and a QBlendEquationArguments with source RGB and alpha set to 1, and destination RGB and alpha set to 1 minus source alpha.
Any ideas how to fix this problem?
(For anyone wondering, I took the images from the T-Less dataset and wrote a program to create ground-truth data for 6D pose estimation)
Similarly to this question, the format of the texture that is being rendered to needs to be set to RGB8_UNorm and not RGBA8_UNorm, i.e. without the alpha channel.
In my QGraphicsScene, I would like to set the background brush to the default widget background - but I can't get it.
Kinda like, for my QGraphicsView,
setBackgroundRole(QPalette::Window);
or
setBackgroundBrush(palette().background().color());
(but setting this I see nothing happening)... I also see nothing happening if I set the view color to a bright red).
So I thought I must set color directly on the QGraphicsScene.
For the QGraphicsScene I am trying all sort of combinations like
setBackgroundBrush(QPalette::color(QPalette::Background));
Nothing will even build, seems I require an object (? a widget ?) - but my scene may not have a widget parent... and all I want is a default palette, I thought there would be a generic way to get that color without having a widget ?
On the scene, this will work...
setBackgroundBrush(Qt::red);
No clue why the view won't show color (even if I set on the view, red brush and on the scene transparent).
You may retrieve the QApplication's current style using the static method style(). From there, you may access the QStyle's standard palette using standardPalette(). Use QPalette's brush method to get a brush for a given ColorRole. Putting it all together you get...
QApplication::style()->standardPalette().brush(QPalette::Background)
This may not be the color you are expecting. Check out the documentation on http://doc.qt.io/qt-4.8/qpalette.html, and try different ColorRole values until you find what you're looking for.
Create a temporary widget instance just to access its palette and get the background color:
QColor bgColor = QWidget().palette().background().color();
But I think you should set the background color in the QGraphicsView widget. You can do that by changing its stylesheet. Something like:
QColor bg = ui->graphicsView->palette().background().color();
ui->graphicsView->setStyleSheet(QString("background-color:") + bg.name(QColor::HexArgb));
Setting a transparent background also works.
first image shows correct (smooth) plotting graph. but when i add any animation like color change, opacity change or text change, graph fails. as you can see in second picture right of graph disappeared...
plot object inherited from qgraphicsproxywidget. registered as qmltype and plotting class inherited from qwtPlot
also did :
QApplication::setGraphicsSystem("raster");
QDeclarativeView::setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing);
any ideas?
without animation: http://i.stack.imgur.com/OMVSu.png
with animation: http://i.stack.imgur.com/9Fhuc.png
solution: it depends on qml scene updating
so change your scene updating mode what you needs.
this solved my needs:
declarativeobject->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
What I want to do:
In PySide, one could override the paintEvent() method of a QWidget to draw a custom widget. The bounding rect can be customized by overriding the boundingRect() method.
How does one do this in JavaFX? My goal is to create a custom Rectangle object, that draws itself smaller than it's bounding rect.
In context:
I'm creating an MS Paint clone in JavaFX. I'm working on the selection box that you use to select/move pixels around. I want the cursor to change to the appropriate resizing cursor when it is near the outside of the selection box.
However, the bounding rect is the same size as the selection box drawn on the screen, so the cursor only changes when it is on top of the box, but not when near. My solution is to set the bounding rect to larger than the actual selection box is, so the cursor change will occur. Then, override it's paintEvent() equivalent to draw a smaller selection box.
Thanks for your help.
I have a similar use case to you, and asked a similiar question here : Drawing transform independent layout bounds in JavaFX.
The JavaFX API is much higher level though than Java2D or PySide (I am assuming from your snippets, because I actually never heard of it ;) ), it does not allow you to override painting of Nodes, nor can you stop a Node from inheriting its parents transform.
This means that you need a seperate Group parallel to your content where you create the selection box and update it according to your needs (content changes etc.).
Example SceneGraph:
Scene
contentGroup
someShapeFromUser
selectionBoxGroup
selectionBoxOfSomeShapeFromUser