如何更改 Qt 的默认选择行为?
How to change Qt's default selection behavior?
我是 QGraphicsView 的新手。所以出于练习的目的,我画了一些形状,如矩形、椭圆、多边形、折线、文本等。
我在这里观察到,每当我们单击这些绘制的对象时(select 使用鼠标单击它们)
对象周围出现虚线矩形,表示对象已 selected.
如果我想改变 Qt 的 selection 的默认行为,该怎么做?
I do not want dotted rectangle around circle, when it will
be clicked by mouse, but that dots should be around its circumference.
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QStyleOptionGraphicsItem>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
public:
virtual void paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include<QGraphicsScene>
#include<QGraphicsView>
#include<QGraphicsEllipseItem>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QGraphicsScene *scene = new QGraphicsScene(this);
QGraphicsView *view = new QGraphicsView(this);
QGraphicsEllipseItem *ellipse = new QGraphicsEllipseItem();
ellipse = scene->addEllipse(2,2,80,80);
//ellipse->setFlag(QGraphicsItem::ItemIsSelectable);
scene->addItem(ellipse);
view->setScene(scene);
ui->verticalLayout->addWidget(view);
}
Widget::~Widget()
{
delete ui;
}
void Widget :: paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
auto copied_option = *option;
copied_option.state &= ~QStyle::State_Selected;
auto selected = option->state & QStyle::State_Selected;
paint(painter, &copied_option, widget);
if (selected) {
QPainterPath path;
path.addEllipse(2,2,80,80);
painter->save();
painter->setBrush(Qt::NoBrush);
painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
painter->drawPath(path);
painter->restore();
}
}
据我所知,没有任何 'built in' 设施可以满足您的需求。在当前 code base 你会看到...
void QGraphicsEllipseItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
Q_D(QGraphicsEllipseItem);
Q_UNUSED(widget);
painter->setPen(d->pen);
painter->setBrush(d->brush);
if ((d->spanAngle != 0) && (qAbs(d->spanAngle) % (360 * 16) == 0))
painter->drawEllipse(d->rect);
else
painter->drawPie(d->rect, d->startAngle, d->spanAngle);
if (option->state & QStyle::State_Selected)
qt_graphicsItem_highlightSelected(this, painter, option);
}
所以选择状态指示器是由 qt_graphicsItem_highlightSelected
绘制的,它直接从 paint
方法调用。 qt_graphicsItem_highlightSelected
本身只是设置了一些基本参数,并以绘制虚线矩形边框结束。
替换默认行为的明显方法是子 class 感兴趣的 QGraphicsItem
class 并覆盖 paint
成员(未经测试)...
#include <QApplication>
#include <QGraphicsEllipseItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPainter>
#include <QStyleOptionGraphicsItem>
class ellipse: public QGraphicsEllipseItem {
public:
explicit ellipse (qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = nullptr)
: QGraphicsEllipseItem(x, y, width, height, parent)
{}
virtual void paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
{
auto copied_option = *option;
copied_option.state &= ~QStyle::State_Selected;
auto selected = option->state & QStyle::State_Selected;
QGraphicsEllipseItem::paint(painter, &copied_option, widget);
if (selected) {
painter->save();
painter->setBrush(Qt::NoBrush);
painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
painter->drawPath(shape());
painter->restore();
}
}
};
int main (int argc, char **argv)
{
QApplication app(argc, argv);
QGraphicsView view;
QGraphicsScene scene;
view.setScene(&scene);
ellipse e(2, 2, 80, 80);
e.setFlag(QGraphicsItem::ItemIsSelectable);
scene.addItem(&e);
view.show();
return app.exec();
}
我是 QGraphicsView 的新手。所以出于练习的目的,我画了一些形状,如矩形、椭圆、多边形、折线、文本等。
我在这里观察到,每当我们单击这些绘制的对象时(select 使用鼠标单击它们)
对象周围出现虚线矩形,表示对象已 selected.
如果我想改变 Qt 的 selection 的默认行为,该怎么做?
I do not want dotted rectangle around circle, when it will be clicked by mouse, but that dots should be around its circumference.
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QStyleOptionGraphicsItem>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
public:
virtual void paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include<QGraphicsScene>
#include<QGraphicsView>
#include<QGraphicsEllipseItem>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QGraphicsScene *scene = new QGraphicsScene(this);
QGraphicsView *view = new QGraphicsView(this);
QGraphicsEllipseItem *ellipse = new QGraphicsEllipseItem();
ellipse = scene->addEllipse(2,2,80,80);
//ellipse->setFlag(QGraphicsItem::ItemIsSelectable);
scene->addItem(ellipse);
view->setScene(scene);
ui->verticalLayout->addWidget(view);
}
Widget::~Widget()
{
delete ui;
}
void Widget :: paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
auto copied_option = *option;
copied_option.state &= ~QStyle::State_Selected;
auto selected = option->state & QStyle::State_Selected;
paint(painter, &copied_option, widget);
if (selected) {
QPainterPath path;
path.addEllipse(2,2,80,80);
painter->save();
painter->setBrush(Qt::NoBrush);
painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
painter->drawPath(path);
painter->restore();
}
}
据我所知,没有任何 'built in' 设施可以满足您的需求。在当前 code base 你会看到...
void QGraphicsEllipseItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
Q_D(QGraphicsEllipseItem);
Q_UNUSED(widget);
painter->setPen(d->pen);
painter->setBrush(d->brush);
if ((d->spanAngle != 0) && (qAbs(d->spanAngle) % (360 * 16) == 0))
painter->drawEllipse(d->rect);
else
painter->drawPie(d->rect, d->startAngle, d->spanAngle);
if (option->state & QStyle::State_Selected)
qt_graphicsItem_highlightSelected(this, painter, option);
}
所以选择状态指示器是由 qt_graphicsItem_highlightSelected
绘制的,它直接从 paint
方法调用。 qt_graphicsItem_highlightSelected
本身只是设置了一些基本参数,并以绘制虚线矩形边框结束。
替换默认行为的明显方法是子 class 感兴趣的 QGraphicsItem
class 并覆盖 paint
成员(未经测试)...
#include <QApplication>
#include <QGraphicsEllipseItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPainter>
#include <QStyleOptionGraphicsItem>
class ellipse: public QGraphicsEllipseItem {
public:
explicit ellipse (qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = nullptr)
: QGraphicsEllipseItem(x, y, width, height, parent)
{}
virtual void paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
{
auto copied_option = *option;
copied_option.state &= ~QStyle::State_Selected;
auto selected = option->state & QStyle::State_Selected;
QGraphicsEllipseItem::paint(painter, &copied_option, widget);
if (selected) {
painter->save();
painter->setBrush(Qt::NoBrush);
painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
painter->drawPath(shape());
painter->restore();
}
}
};
int main (int argc, char **argv)
{
QApplication app(argc, argv);
QGraphicsView view;
QGraphicsScene scene;
view.setScene(&scene);
ellipse e(2, 2, 80, 80);
e.setFlag(QGraphicsItem::ItemIsSelectable);
scene.addItem(&e);
view.show();
return app.exec();
}