QGraphicsView:绘制矩形渐变
QGraphicsView: Paint Rectangular Gradient
我正在尝试绘制矩形渐变作为 QGraphicsView 的背景。
这张图片是我正在努力实现的示例:
注意边框周围的光线渐变。
我尝试使用 4 个 QLinearGradients 从 window 的每个边界到相反的边界(从右到左,从上到下等等)。我认为这种方法不是很有效(绘制这么多渐变对象)。也许将 Spread 设置为 ReflectSpread 的单个 QLinearGradient 就足够了,但我有一个定位问题。这个想法是渐变应该像遮阳板,像相机的框架。无论 QGraphicsView 的大小或比例如何,它看起来应该总是一样的。
这是 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);
我尝试在边框周围使用样式表,但它没有给我想要的结果。似乎渐变不能应用于边框,只能应用于工具提示。最小示例:
#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();
}
我尝试使用 样式表 创建它,这是我的结果:
我在我的 centralwidget
中添加了一个 graphicsView
小部件并添加了这个 样式表:
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;
我试过你的颜色,但是如果你玩它的RGB,你可以得到你想要的颜色。
我认为这是最干净的解决方案,因为通过更改视图的大小,所有内容都会发生相同的变化,并且样式保持不变。
编辑和更新:
您不应该将 setBackgroundBrush(QColor(35, 41, 56));
添加到 QGraphicsView
和 View
class 中。我删除了这一行,而是将其作为 setStyleSheet 添加到 MainWindow 中。像这样:
在视图中 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);
}
并在主窗口中 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);
}
这是结果:
我找到了一个解决方案,实际上是两个。这个想法是在 QGraphicsView 的边界绘制渐变。效果应该是恒定的,不受平移视图或调整小部件大小的影响。结果:
https://i.gyazo.com/af979432e86b9ecf3848a0114d950531.gif
使用 QGraphicsView 的矩形在 QGraphicsView::drawBackground() 中绘制渐变,但确保不缓存背景。确保未设置 setCacheMode(CacheBackground);。如果这样设置,就会有伪影。
QLinearGradient leftGrad;
leftGrad.setStart(rect.left(), 0);
leftGrad.setFinalStop(rect.left() + 200, 0);
leftGrad.setColorAt(0.0, gradientColor);
leftGrad.setColorAt(gradientPosition, Qt::transparent);
painter->fillRect(rect, leftGrad);
改为在 QGraphicsView::drawForeground() 中绘制渐变。这允许保留后台缓存以进行优化。
我正在尝试绘制矩形渐变作为 QGraphicsView 的背景。
这张图片是我正在努力实现的示例:
注意边框周围的光线渐变。
我尝试使用 4 个 QLinearGradients 从 window 的每个边界到相反的边界(从右到左,从上到下等等)。我认为这种方法不是很有效(绘制这么多渐变对象)。也许将 Spread 设置为 ReflectSpread 的单个 QLinearGradient 就足够了,但我有一个定位问题。这个想法是渐变应该像遮阳板,像相机的框架。无论 QGraphicsView 的大小或比例如何,它看起来应该总是一样的。
这是 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);
我尝试在边框周围使用样式表,但它没有给我想要的结果。似乎渐变不能应用于边框,只能应用于工具提示。最小示例:
#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();
}
我尝试使用 样式表 创建它,这是我的结果:
我在我的 centralwidget
中添加了一个 graphicsView
小部件并添加了这个 样式表:
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;
我试过你的颜色,但是如果你玩它的RGB,你可以得到你想要的颜色。 我认为这是最干净的解决方案,因为通过更改视图的大小,所有内容都会发生相同的变化,并且样式保持不变。
编辑和更新:
您不应该将 setBackgroundBrush(QColor(35, 41, 56));
添加到 QGraphicsView
和 View
class 中。我删除了这一行,而是将其作为 setStyleSheet 添加到 MainWindow 中。像这样:
在视图中 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);
}
并在主窗口中 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);
}
这是结果:
我找到了一个解决方案,实际上是两个。这个想法是在 QGraphicsView 的边界绘制渐变。效果应该是恒定的,不受平移视图或调整小部件大小的影响。结果: https://i.gyazo.com/af979432e86b9ecf3848a0114d950531.gif
使用 QGraphicsView 的矩形在 QGraphicsView::drawBackground() 中绘制渐变,但确保不缓存背景。确保未设置 setCacheMode(CacheBackground);。如果这样设置,就会有伪影。
QLinearGradient leftGrad; leftGrad.setStart(rect.left(), 0); leftGrad.setFinalStop(rect.left() + 200, 0); leftGrad.setColorAt(0.0, gradientColor); leftGrad.setColorAt(gradientPosition, Qt::transparent); painter->fillRect(rect, leftGrad);
改为在 QGraphicsView::drawForeground() 中绘制渐变。这允许保留后台缓存以进行优化。