如何在 Qt 中的按钮后面画线?
How to draw line behind buttons in Qt?
问题
在自定义小部件中,我想画线(使用 QPainter
)连接 QGridLayout
中的按钮。线条应该在按钮后面,为了
- a) 不干扰中间的按钮
- b) 允许在按钮的中心而不是边缘开始线条
考虑到 的想法,我几乎可以在我的 GUI 应用程序(下面的源代码)中实现一个简单的基本版本 运行。
只要我使用 QPushButton
和标准的 Qt 样式,它就像一个魅力(左),但是,因为我想使用自定义样式,线条重叠(右):
什么 属性 或机制导致了这种行为?
代码
MyFrame.h:
#include <QFrame>
class MyFrame : public QFrame
{
public:
MyFrame();
virtual ~MyFrame() = default;
};
MyFrame.cpp:
#include "MyFrame.h"
#include "LineDrawWidget.h"
#include <QVBoxLayout>
#include <QGridLayout>
#include <QPushButton>
#include <QButtonGroup>
MyFrame::MyFrame()
{
auto* mainLayout = new QVBoxLayout(this);
auto* buttonLayout = new QGridLayout();
QPushButton* button;
auto* buttons = new QButtonGroup();
for (int i = 0; i < 3; ++i) {
button = new QPushButton();
button->setText(QString::number(i+1));
button->setFixedHeight(40);
button->setFixedWidth(40);
button->setStyleSheet("QPushButton { color : black; background-color : white; }");
button->setStyleSheet("QPushButton { border-style : outset; border-color: black; border-width: 2px; border-radius: 6px; }");
buttonLayout->addWidget(button);
buttons->addButton(button, i);
}
auto* lineDraw = new LineDrawWidget(
buttons->button(0),
buttons->button(2));
lineDraw->setLayout(buttonLayout);
mainLayout->addWidget(lineDraw);
}
LineDrawWidget.h:
#include <QWidget>
class LineDrawWidget : public QWidget
{
public:
LineDrawWidget(
QWidget* from,
QWidget* to,
QWidget* parent = nullptr);
virtual ~LineDrawWidget() = default;
protected:
virtual void paintEvent(QPaintEvent* e) final override;
private:
QWidget* _from;
QWidget* _to;
};
LineDrawWidget.cpp:
#include "LineDrawWidget.h"
#include <QPainter>
LineDrawWidget::LineDrawWidget(
QWidget* from,
QWidget* to,
QWidget* parent) :
QWidget(parent),
_from(from),
_to(to)
{
}
void LineDrawWidget::paintEvent(QPaintEvent* e)
{
(void)e;
QPainter painter(this);
QPoint start = _from->mapToGlobal(_from->rect().bottomLeft());
QPoint end = _to->mapToGlobal(_to->rect().topRight());
painter.drawLine(mapFromGlobal(start), mapFromGlobal(end));
}
我认为问题是针对单个 QPushButton
对 setStyle
的两次单独调用——第二次调用似乎重置了其中不存在的所有属性。尝试将所有内容放在一次调用中...
button->setStyleSheet("color : black; background-color : white; border-style : outset; border-color: black; border-width: 2px; border-radius: 6px;");
似乎对我有用。
问题
在自定义小部件中,我想画线(使用 QPainter
)连接 QGridLayout
中的按钮。线条应该在按钮后面,为了
- a) 不干扰中间的按钮
- b) 允许在按钮的中心而不是边缘开始线条
考虑到
只要我使用 QPushButton
和标准的 Qt 样式,它就像一个魅力(左),但是,因为我想使用自定义样式,线条重叠(右):
什么 属性 或机制导致了这种行为?
代码
MyFrame.h:
#include <QFrame>
class MyFrame : public QFrame
{
public:
MyFrame();
virtual ~MyFrame() = default;
};
MyFrame.cpp:
#include "MyFrame.h"
#include "LineDrawWidget.h"
#include <QVBoxLayout>
#include <QGridLayout>
#include <QPushButton>
#include <QButtonGroup>
MyFrame::MyFrame()
{
auto* mainLayout = new QVBoxLayout(this);
auto* buttonLayout = new QGridLayout();
QPushButton* button;
auto* buttons = new QButtonGroup();
for (int i = 0; i < 3; ++i) {
button = new QPushButton();
button->setText(QString::number(i+1));
button->setFixedHeight(40);
button->setFixedWidth(40);
button->setStyleSheet("QPushButton { color : black; background-color : white; }");
button->setStyleSheet("QPushButton { border-style : outset; border-color: black; border-width: 2px; border-radius: 6px; }");
buttonLayout->addWidget(button);
buttons->addButton(button, i);
}
auto* lineDraw = new LineDrawWidget(
buttons->button(0),
buttons->button(2));
lineDraw->setLayout(buttonLayout);
mainLayout->addWidget(lineDraw);
}
LineDrawWidget.h:
#include <QWidget>
class LineDrawWidget : public QWidget
{
public:
LineDrawWidget(
QWidget* from,
QWidget* to,
QWidget* parent = nullptr);
virtual ~LineDrawWidget() = default;
protected:
virtual void paintEvent(QPaintEvent* e) final override;
private:
QWidget* _from;
QWidget* _to;
};
LineDrawWidget.cpp:
#include "LineDrawWidget.h"
#include <QPainter>
LineDrawWidget::LineDrawWidget(
QWidget* from,
QWidget* to,
QWidget* parent) :
QWidget(parent),
_from(from),
_to(to)
{
}
void LineDrawWidget::paintEvent(QPaintEvent* e)
{
(void)e;
QPainter painter(this);
QPoint start = _from->mapToGlobal(_from->rect().bottomLeft());
QPoint end = _to->mapToGlobal(_to->rect().topRight());
painter.drawLine(mapFromGlobal(start), mapFromGlobal(end));
}
我认为问题是针对单个 QPushButton
对 setStyle
的两次单独调用——第二次调用似乎重置了其中不存在的所有属性。尝试将所有内容放在一次调用中...
button->setStyleSheet("color : black; background-color : white; border-style : outset; border-color: black; border-width: 2px; border-radius: 6px;");
似乎对我有用。