Название: QGraphicsScene. Несоответствие координат.
Отправлено: Lenidoxll от Январь 10, 2021, 22:48
На сцене есть два итема. Хочется, чтобы их начала координат совпадали с началом координат сцены, но почему-то добиться этого не получается. Пожалуйста, подскажите, где же у меня допущена ошибка? SliderCrankLinkage.h: class SliderCrankLinkage : public QGraphicsView { public: SliderCrankLinkage(QWidget* parent = nullptr);
QGraphicsScene* scene; Link* link; GraphicsBearing* bearing; };
SliderCrankLinkage.cpp: SliderCrankLinkage::SliderCrankLinkage(QWidget *parent) : QGraphicsView(parent) { scene = new QGraphicsScene(this); QRect rect(-300, -300, 600, 600); scene->addRect(rect);
QPoint O(0, 0), A(100, 0), B(-300, 200), E(200, 0), M(0, 200);
QGraphicsLineItem* Ox = new QGraphicsLineItem(0, 0, 200, 0); Ox->setPen(QPen(Qt::red, 10, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); QGraphicsLineItem* Oy = new QGraphicsLineItem(0, 0, 0, 200); Oy->setPen(QPen(Qt::red, 10, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); scene->addItem(Ox); scene->addItem(Oy);
QGraphicsObject* link = new Link(A, B); scene->addItem(link); link->setPos(-A.x(), -A.y());
QPointF OriginPoint = link->pos(); QGraphicsObject* bearing = new GraphicsBearing(O); QLineF nOx(O, E), nOy(O, M); QGraphicsLineItem* newOx = new QGraphicsLineItem(nOx); newOx->setPen(QPen(Qt::darkCyan, 7, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); QGraphicsLineItem* newOy = new QGraphicsLineItem(nOy); newOy->setPen(QPen(Qt::darkCyan, 7, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); scene->addItem(newOx); scene->addItem(newOy);
//ПРОБЛЕМА ТУТ ---> scene->addItem(bearing);
// QPointF OriginPoint = link->pos(); // bearing->setPos(OriginPoint);
QGraphicsLineItem* minusOx = new QGraphicsLineItem(0, 0, -200, 0); minusOx->setPen(QPen(Qt::yellow, 10, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); QGraphicsLineItem* minusOy = new QGraphicsLineItem(0, 0, 0, -200); minusOy->setPen(QPen(Qt::yellow, 10, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); scene->addItem(minusOx); scene->addItem(minusOy);
this->setScene(scene); this->setRenderHint(QPainter::Antialiasing); this->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); this->setBackgroundBrush(QColor(230, 200, 167)); this->setWindowTitle("Another name"); }
GraphicsBearing.h: class GraphicsBearing : public QGraphicsObject { public: GraphicsBearing(QPoint O = QPoint(0, 0), QGraphicsItem *parent = nullptr); GraphicsBearing(QPointF O = QPoint(0, 0), QGraphicsItem *parent = nullptr);
QRectF boundingRect() const override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override; QPoint O; QPointF OF; };
GraphicsBearing.cpp: GraphicsBearing::GraphicsBearing(QPoint point, QGraphicsItem *parent) : QGraphicsObject(parent) { O = point; }
GraphicsBearing::GraphicsBearing(QPointF point, QGraphicsItem *parent) { OF = point; }
QRectF GraphicsBearing::boundingRect() const { return QRectF(0, 0, 110, 130); }
void GraphicsBearing::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); painter->setPen(QPen(Qt::black, 5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); QLine AB(0, 0, 60, 0), BC(0, 0, 60, 0), CA(0, 0, 60, 0);
if (O.isNull()) painter->translate(OF); else painter->translate(O); painter->translate(55, 65); painter->rotate(+60.0); painter->drawLine(AB);
painter->rotate(+60.0); painter->drawLine(BC); painter->rotate(-60.0); painter->translate(60.0, 0); painter->rotate(+120.0); painter->drawLine(CA);
painter->translate(30.0, 0); painter->drawLine(50, 0, -50, 0); painter->setPen(Qt::NoPen); painter->setBrush(QBrush(Qt::black, Qt::BDiagPattern)); painter->drawRect(50, 0, -100, -25);
painter->translate(-30.0, 0); painter->rotate(-120.0); painter->translate(-60.0, 0); painter->rotate(-60.0); painter->setPen(QPen(Qt::black, 5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->setBrush(Qt::NoBrush); painter->drawEllipse(-40, -40, 80, 80); painter->drawEllipse(-25, -25, 50, 50);
painter->setPen(Qt::magenta); painter->drawLine(0, 0, 200, 0); painter->drawLine(0, 0, 0, 200); }
Насколько я понимаю, вообще-то когда я на сцену добавляю итем, начало координат этого итема как раз таки должно совпадать с началом координат сцены! Однако почему-то bearing упорно игнорирует вообще всякое существование начала координат сцены (точки О для простоты), кроме тех, на которых он появился с самого начала! С link-ом была похожая проблема, но все-таки в конце концов как-то удалось выкрутиться и добиться того, чтобы link, являющийся обычным отрезком, начинался бы из начала координат, а вот с bearing-ом ну ни в какую не выходит!!! Игнорируются все методы, причем, что самое интересное, судя по отладке, bearing реально располагается в начале координат! Однако множественное рисование прямых вдоль осей х и у, сходящихся всегда в точке (0, 0), убеждает, что все-таки начало координат находится в другом месте, не там, где bearing! Для наглядности внутри самого класса bearing тоже есть прямые, идущие вдоль x и у. Мне ужасно интересно, где же все-таки ошибка! Или я чего-то не понимаю? ???
Название: Re: QGraphicsScene. Несоответствие координат.
Отправлено: Lenidoxll от Январь 11, 2021, 00:07
А впрочем, знаете, ни черта с link-ом проблема не решилась. Если сделать еще один link, то программа вылетает с ошибкой: Приложение остановлено, так как оно получило сигнал от операционной системы.
Сигнал: SIGSEGV Назначение: Segmentation fault Вроде эта ошибка должна означать, что я вызываю нулевой указатель, но что именно за указатель - непонятно, потому что сам новый link (linkBC) все-таки есть и объявлен, судя по отладке. Мне кажется, эти проблемы - одного поля ягоды. Надеюсь, я просто не понимаю, как работают QGraphicsScene и QGraphicsItem. Link.h: class Link : public QGraphicsObject { Q_OBJECT public: explicit Link(int x1, int y1, int x2, int y2, QGraphicsItem *parent = nullptr); explicit Link(QPoint A, QPoint B, QGraphicsItem *parent = nullptr); QRectF boundingRect() const override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override; // void setPoint1(int x, int y); // void setPoint2(int x, int y); private: QPoint point1; QPoint point2; };
Link.cpp: Link::Link(int x1, int y1, int x2, int y2, QGraphicsItem *parent) : QGraphicsObject(parent) { QGraphicsLineItem* Ox = new QGraphicsLineItem(200, 0, 0, 0, this); Ox->setPen(QPen(Qt::yellow, 5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); QGraphicsLineItem* Oy = new QGraphicsLineItem(0, 200, 0, 0, this); Oy->setPen(QPen(Qt::yellow, 5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); point1.setX(x1); point1.setY(y1); point2.setX(x2); point2.setY(y2); } Link::Link(QPoint A, QPoint B, QGraphicsItem *parent) : QGraphicsObject(parent) { point1 = A; point2 = B; } QRectF Link::boundingRect() const { int x, y; if (point1.x()*point2.x() >= 0) x = abs(point1.x() - point2.x()); else x = abs(point1.x()) + abs(point2.x()); if (point1.y()*point2.y() >= 0) y = abs(point1.y() - point2.y()); else y = abs(point1.y()) + abs(point2.y()); return QRectF(0, 0, x, y); } void Link::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); QLine line(point1.x(), point1.y(), point2.x(), point2.y()); painter->setPen(QPen(Qt::black, 5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->drawLine(line); painter->translate(point1); painter->setPen(Qt::blue); painter->drawLine(-200, 0, 200, 0); painter->drawLine(0, -200, 0, 200); }
SliderCrankLinkage.cpp после добавления linkBC: SliderCrankLinkage::SliderCrankLinkage(QWidget *parent) : QGraphicsView(parent) { scene = new QGraphicsScene(this); QRect rect(-300, -300, 600, 600); scene->addRect(rect); QPoint O(0, 0), A(100, 0), B(-300, 200), C(300, 300), E(200, 0), M(0, 200); QGraphicsLineItem* Ox = new QGraphicsLineItem(0, 0, 200, 0); Ox->setPen(QPen(Qt::red, 10, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); QGraphicsLineItem* Oy = new QGraphicsLineItem(0, 0, 0, 200); Oy->setPen(QPen(Qt::red, 10, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); scene->addItem(Ox); scene->addItem(Oy); QGraphicsObject* linkAB = new Link(A, B); scene->addItem(linkAB); linkAB->setPos(-A.x(), -A.y()); QGraphicsObject* linkBC = new Link(B, C); scene->addItem(linkBC); //linkBC->setPos(B); QPointF OriginPoint = link->pos(); QGraphicsObject* bearing = new GraphicsBearing(O); QLineF nOx(O, E), nOy(O, M); QGraphicsLineItem* newOx = new QGraphicsLineItem(nOx); newOx->setPen(QPen(Qt::darkCyan, 7, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); QGraphicsLineItem* newOy = new QGraphicsLineItem(nOy); newOy->setPen(QPen(Qt::darkCyan, 7, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); scene->addItem(newOx); scene->addItem(newOy); scene->addItem(bearing); // QPointF OriginPoint = link->pos(); // bearing->setPos(OriginPoint); QGraphicsLineItem* minusOx = new QGraphicsLineItem(0, 0, -200, 0); minusOx->setPen(QPen(Qt::yellow, 10, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); QGraphicsLineItem* minusOy = new QGraphicsLineItem(0, 0, 0, -200); minusOy->setPen(QPen(Qt::yellow, 10, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); scene->addItem(minusOx); scene->addItem(minusOy); this->setScene(scene); this->setRenderHint(QPainter::Antialiasing); this->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); this->setBackgroundBrush(QColor(230, 200, 167)); this->setWindowTitle("Another name"); }
Название: Re: QGraphicsScene. Несоответствие координат.
Отправлено: Racheengel от Январь 12, 2021, 12:58
Центр координат сцены (точка 0,0) - это по умолчанию центр экрана. Почему-то bearing->setPos(...) в коде закомментирован, а значит, по умолчанию он будет помещён в центр.
|