C++和Qt - 2D图形问题

3
使命:通过逐点添加,自动剪切在一个图表上绘制两条不同颜色的线。
那么,我正在做什么?创建GraphWidget类,继承自QGraphicsView。创建QGraphicsScene成员。创建2个QPainterPath实例,并将它们添加到graphicsScene中。
然后,最终调用graphWidget.Redraw(),其中为两个实例调用QPainterPath.lineTo()。我期望在图形视图中看到这些线的外观,但是没有显示出来。
我已经从Qt的文档和论坛中读得疲惫不堪了。我做错了什么?

2
请贴出相关的代码片段,这将帮助我们了解您迄今为止所做的工作。 - Evan Teran
2个回答

4

我们需要更多的信息,出了什么问题?窗口是否出现?线条是否没有画出来?同时,如果您想尝试,请使用此示例代码:)编辑:更新以显示更新。

#include ...

class QUpdatingPathItem : public QGraphicsPathItem {
    void advance(int phase) {
        if (phase == 0)
            return;
        int x = abs(rand()) % 100;
        int y = abs(rand()) % 100;
        QPainterPath p = path();
        p.lineTo(x, y);
        setPath(p);
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene s;
    QGraphicsView v(&s);

    QUpdatingPathItem item;
    item.setPen(QPen(QColor("red")));
    s.addItem(&item);
    v.show();

    QTimer *timer = new QTimer(&s);
    timer->connect(timer, SIGNAL(timeout()), &s, SLOT(advance()));
    timer->start(1000);

    return a.exec();
}

你应该得到类似这样的东西:

嗯...

任何QGraphicsPathItem中的路径当然可以稍后更新。你可能希望将原始绘图路径保留在某个地方,以避免由所有路径复制引起的性能损失(我不确定QPainterPath是否隐式共享...)。
QPainterPath p = gPath.path();
p.lineTo(0, 42);
gPath.setPath(p);

动画

看起来你正在尝试进行某种形式的动画/即时更新。在Qt中有整个框架可以实现这一点。最简单的形式是子类化QGraphicsPathItem,重新实现其advance()槽以自动从运动中获取下一个点。然后只需要按所需频率调用s.advance()即可。

http://doc.trolltech.com/4.5/qgraphicsscene.html#advance


窗口出现了。然而没有画线。如果在调用scene.addPath()之前添加它们,则它们会出现,但是(如您的示例中所示)如果我更改路径,则GraphicsView不会更新,新线条不会出现。 - peterdemin
哦,我想我找到了这个错误......组合板路径项 = new QGraphicsPathItem(); 场景添加路径(nature_path_item->path(),自然笔); 没有跟踪更改。感谢您的示例。 - peterdemin

1

埃文·特兰,对于那条评论很抱歉。

// Constructor:
GraphWidget::GraphWidget( QWidget *parent ) :
        QGraphicsView(parent),
        bounds(0, 0, 0, 0)
{
    setScene(&scene);
    QPen board_pen(QColor(255, 0, 0));
    QPen nature_pen(QColor(0, 0, 255));
    nature_path_item = scene.addPath( board_path, board_pen );
    board_path_item  = scene.addPath( nature_path, nature_pen );
}

// Eventually called func:
void GraphWidget::Redraw() {
    if(motion) {
        double nature[6];
        double board[6];
        // Get coords:
        motion->getNature(nature);
        motion->getBoard(board);
        if(nature_path.elementCount() == 0) {
            nature_path.moveTo( nature[0], nature[1] );
        } else {
            nature_path.lineTo( nature[0], nature[1] );
        }
        if(board_path.elementCount() == 0) {
            board_path.moveTo( board[0], board[1] );
        } else {
            board_path.lineTo( board[0], board[1] );
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接