The 2px border problem in QGraphicsView

来源:互联网 发布:微商团队怎么优化 编辑:程序博客网 时间:2024/04/27 14:50

Graphics View Framework  编程中,发现 在QGraphicsView 的resizeEvent函数 中调用

void QGraphicsView::fitInView ( const QRectF & rect, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio )

函数,虽然可以实现,scene 的size随view的size变化而变化,但是边框总是无法填满,到现在才找到了比较合适的解决办法:

参考1:http://www.qtforum.org/article/35467/the-2px-border-problem-in-qgraphicsview.html;

void Widget::resizeEvent(QResizeEvent *event){    Q_UNUSED(event);    QTransform matrix(1,0,0,0,1,0,0,0,1);    matrix.scale(this->width()/this->sceneRect().width(),                 this->height()/this->sceneRect().height());    this->setTransform(matrix);}

this is worked,但是 相当于Qt::IgnoreAspectRatio

 QTransform matrix(1,0,0,0,1,0,0,0,1); qreal xscale =this->width()/this->sceneRect().width(); qreal yscale = this->height()/this->sceneRect().height(); xscale = yscale = qMin(xscale,yscale); matrix.scale(xscale,yscale);

this is worked, 但是 相当于 Qt::KeepAspectRatio

同时上述两种方案,有滚动条的问题,即使隐藏滚动条,界面也会不可避免的出现抖动效果。

参考2:qt 源码中关于fitInView的内部函数;

void QGraphicsView::fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRatioMode){    Q_D(QGraphicsView);    if (!d->scene || rect.isNull())        return;    // Reset the view scale to 1:1.    QRectF unity = d->matrix.mapRect(QRectF(0, 0, 1, 1));    if (unity.isEmpty())        return;    scale(1 / unity.width(), 1 / unity.height());    // Find the ideal x / y scaling ratio to fit \a rect in the view.    <span style="color:#ff0000;">int margin = 2;</span>    QRectF viewRect = viewport()->rect().adjusted(margin, margin, -margin, -margin);    if (viewRect.isEmpty())        return;    QRectF sceneRect = d->matrix.mapRect(rect);    if (sceneRect.isEmpty())        return;    qreal xratio = viewRect.width() / sceneRect.width();    qreal yratio = viewRect.height() / sceneRect.height();    // Respect the aspect ratio mode.    switch (aspectRatioMode) {    case Qt::KeepAspectRatio:        xratio = yratio = qMin(xratio, yratio);        break;    case Qt::KeepAspectRatioByExpanding:        xratio = yratio = qMax(xratio, yratio);        break;    case Qt::IgnoreAspectRatio:        break;    }    // Scale and center on the center of \a rect.    scale(xratio, yratio);    centerOn(rect.center());}

int margin = 2;源码中指明了margin 的值是2px, 这可能就是,2px-border 的问题所在,而且参考1中的两个方案,也借鉴了源码的部分内容。


目前最优解决方案如下:

    QTransform matrix(1,0,0,0,1,0,0,0,1);    qreal xratio = this->viewport()->rect().width() / this->sceneRect().width();    qreal yratio = this->viewport()->rect().height() / this->sceneRect().height();    xratio = yratio = qMin(yratio, xratio);    matrix.scale(xratio, yratio);    this->setTransform(matrix);

综合上述几种方法,总算是得到列自己想要的这套方案:

1.几乎实现无border的自适应(这里说的几乎,仔细看还是会有border残留的,这可能和resizeEvent() 变换中有些影响,算是目前最好的方案,以后找到更好的更新);

2.没有滚动条的麻烦,已经抖动效果;

但是假若仅仅是要修改背景图的话, 下面这样做,也是一种好的方法:

void View::paintEvent(QPaintEvent *event){    QGraphicsView::paintEvent(event);    QPainter painter(this->viewport());    painter.fillRect(this->viewport()->rect(),                     QPixmap(":/beijing").scaled(this->viewport()->size(), Qt::KeepAspectRatio)                     );}

20151210:

padding: -2px;

完美解决

0 0
原创粉丝点击