I'm trying to paint a rectangular gradient as the background for a QGraphicsView.
This image is an example of what I'm trying to achieve:
Notice the light gradient around the borders.
I tried using 4 QLinearGradients going from each border of the window to the opposite(From right to left, from top to bottom and so on). I don't think this approach is very efficient(painting so many gradient objects). Maybe a single QLinearGradient with the Spread set to ReflectSpread is enough, but I have a positioning issue. The idea is that the gradient should be like a visor, like the frame of a camera. It should always look the same regardless of QGraphicsView size or scale.
This is the code for the QLinearGradient:
QLinearGradient lGrad;
lGrad.setSpread(QGradient::ReflectSpread);
lGrad.setStart(0, 500);
lGrad.setColorAt(0, Qt::red);
lGrad.setColorAt(1, Qt::blue);
painter->fillRect(rect, lGrad);
I tried using a stylesheet around the border but it doesn't give me the desired results. It seems that gradients cannot be applied to borders, only to tooltips. Minimal example:
#include <QGraphicsView>
// View
class View : public QGraphicsView
{
Q_OBJECT
public:
explicit View(QWidget* parent = nullptr)
{
// Stylesheet
setStyleSheet(
"border-left:40px solid qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 0, 0,150), stop:1 rgba(0, 0, 0, 0) );"
"border-right:40px solid qlineargradient(spread:pad, x1:1, y1:0, x2:0, y2:0, stop:0 rgba(0, 0, 0,150), stop:1 rgba(0, 0, 0, 0) );"
"border-top:40px solid qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(0, 0, 0,150), stop:1 rgba(0, 0, 0, 0) );"
"border-bottom:40px solid qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(0, 0, 0,150), stop:1 rgba(0, 0, 0, 0) );"
"border-radius: 0.5px;"
"padding: 1px;"
"margin: 0px;"
"spacing: 0px;"
);
// Hidden because the stylesheet adds colors to them
setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setDragMode(QGraphicsView::ScrollHandDrag);
setBackgroundBrush(QColor(35, 41, 56));
setCacheMode(CacheBackground);
setViewportUpdateMode(BoundingRectViewportUpdate);
setRenderHint(QPainter::Antialiasing);
setTransformationAnchor(AnchorUnderMouse);
scale(qreal(0.8), qreal(0.8));
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
}
void mousePressEvent(QMouseEvent *event) override
{
QGraphicsView::mousePressEvent(event);
if (event->button() == Qt::LeftButton)
{
_clickPos = mapToScene(event->pos());
}
}
void mouseMoveEvent(QMouseEvent *event) override
{
QGraphicsView::mouseMoveEvent(event);
if (scene()->mouseGrabberItem() == nullptr && event->buttons() == Qt::LeftButton)
{
if ((event->modifiers() & Qt::ShiftModifier) == 0)
{
QPointF difference = _clickPos - mapToScene(event->pos());
setSceneRect(sceneRect().translated(difference.x(), difference.y()));
}
}
}
}
// Main
#include <QMainWindow>
#include <QGraphicsScene>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
auto scene = new QGraphicsScene;
auto view = new View;
view->setScene(scene);
auto window = new QMainWindow;
window->setCentralWidget(view);
window->show();
return app.exec();
}
CodePudding user response:
I tried to create it by using Stylesheet and this is my result:
I add one graphicsView
Widget in my centralwidget
and add this Stylesheet:
border-left:20px solid qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(32, 180, 214,150), stop:1 rgba(0, 0, 0, 0) );
border-right:20px solid qlineargradient(spread:pad, x1:1, y1:0, x2:0, y2:0, stop:0 rgba(32, 180, 214,150), stop:1 rgba(0, 0, 0, 0) );
border-top:20px solid qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(32, 180, 214,150), stop:1 rgba(0, 0, 0, 0) );
border-bottom:20px solid qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(32, 180, 214,150), stop:1 rgba(0, 0, 0, 0) );
border-radius: 0.5px;
padding: 1px;
margin: 0px;
spacing: 0px;
I tried to get your color, but if you play with its RGB, you can get the color you want. I think this is the cleanest solution possible because by changing the size of the view, everything changes the same and the Style remains constant.
Edited and Updated:
you shouldn't add setBackgroundBrush(QColor(35, 41, 56));
to your QGraphicsView
and View
class . I remove this line and instead I add this in MainWindow as setStyleSheet. like this :
in View class :
View::View()
{
// Stylesheet
setStyleSheet(
"border-left:40px solid qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 0, 0,150), stop:1 rgba(0, 0, 0, 0) );"
"border-right:40px solid qlineargradient(spread:pad, x1:1, y1:0, x2:0, y2:0, stop:0 rgba(0, 0, 0,150), stop:1 rgba(0, 0, 0, 0) );"
"border-top:40px solid qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(0, 0, 0,150), stop:1 rgba(0, 0, 0, 0) );"
"border-bottom:40px solid qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(0, 0, 0,150), stop:1 rgba(0, 0, 0, 0) );"
"border-radius: 0.5px;"
"padding: 1px;"
"margin: 0px;"
"spacing: 0px;"
);
// Hidden because the stylesheet adds colors to them
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setDragMode(QGraphicsView::ScrollHandDrag);
// setBackgroundBrush(QColor(35, 41, 56));
setCacheMode(CacheBackground);
setViewportUpdateMode(BoundingRectViewportUpdate);
setRenderHint(QPainter::Antialiasing);
setTransformationAnchor(AnchorUnderMouse);
scale(qreal(0.8), qreal(0.8));
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
}
and in MainWindow class:
MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setStyleSheet("background-color: rgb(35, 41, 43);");
auto scene = new QGraphicsScene;
auto view = new View;
view->setScene(scene);
setCentralWidget(view);
}
This is The Result: