我正在开发一个视频播放器,使用QGraphicsView
来显示视频。 QGraphicsView
正在显示QGraphicsScene
个QGraphicsPixmapItem
,其中包含当前视频帧。视图的背景是黑色的。
只要框架小于视图,一切都会正常,视频框架显示在视图的中心,视图的其余部分为黑色。当视图与框架具有相同的大小时,仅显示框架,(显然)没有背景。当视频帧大于视图时,会显示滚动条,以便用户可以滚动以查看帧的其他部分。
问题:当显示滚动条时,可以滚动浏览视频帧。底部和右侧的边距为8像素,背景可见。如果视频帧大于视图,则应该没有可见的背景,并且无法滚动浏览视频帧。
我将问题简化为演示此问题的简短源代码,在绿色背景的QPixmap
中显示200x200像素的红色QGraphicsView
。
#include <QtGui/QApplication>
#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsView>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QMainWindow window;
QPixmap pixmap(200, 200);
pixmap.fill(QColor(255, 0, 0));
QGraphicsScene scene(&window);
scene.addPixmap(pixmap);
QGraphicsView view(&window);
view.setBackgroundBrush(QColor(0, 255, 0));
view.setScene(&scene);
window.setCentralWidget(&view);
window.show();
window.resize(199, 199);
return app.exec();
}
我还制作了问题图片(示例代码中未包含黑色边框):http://imgur.com/4X5eyhC
在左侧窗口中,QGraphicsView
与矩形的大小相同,在右侧窗口中它稍微小一些,因此会显示滚动条。并且背景是可见的(它不应该是可见的)。
我已经尝试设置了sceneRect以及QWidget
,QGraphicsView
和QGraphicsScene
的各种其他属性,但发现没有任何改变此问题的任何内容。
我也尝试在虚拟机中运行示例问题,以排除我的Qt / KDE版本有错误的可能性。
我不知道为什么有滚动条时会突然显示背景。我怎么能摆脱它呢?如果那是不可能的,你是否知道如何解决这个问题?
提前致谢。
答案 0 :(得分:2)
您所看到的是QGraphicsView之外的窗口区域。您可能还会发现可以调整窗口大小并显示更多边框。
要修复它,请将窗口大小限制为QGraphicsView的大小。由于您没有在示例代码中设置它,因此它将是像素图的大小。
因此在声明窗口后添加这些行: -
window.setMaximumWidth(200);
window.setMaximumHeight(200);
执行此操作会限制窗口的大小调整大于这些值,因此如果您需要调整窗口大小,则需要更大的QGraphicsView和QGraphicsScene。
答案 1 :(得分:2)
问题是QGraphicsView :: fitInView()的一个错误,他们并不关心:https://bugreports.qt.io/browse/QTBUG-11945
创建新视图时,只需删除视图的边距即可代替重新实现自己的fitInView。
var passedAccounts = customers.Where(s => s.Orders.All(o => o.PassFails == "P"));
答案 2 :(得分:1)
我尝试了问题的片段,但在Python下使用Qt的PySide包装器。代码几乎相同。
import sys
from PySide import QtGui
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = QtGui.QMainWindow()
pixmap = QtGui.QPixmap(200, 200)
pixmap.fill(QtGui.QColor(255, 0, 0))
scene = QtGui.QGraphicsScene(window)
scene.addPixmap(pixmap)
view = QtGui.QGraphicsView(window)
view.setBackgroundBrush(QtGui.QColor(0, 255, 0))
view.setScene(scene)
window.setCentralWidget(view)
window.show()
window.resize(199, 199)
sys.exit(app.exec_())
滚动条出现但我看不到任何绿色区域!
我猜因为它只是QT库的一个包装器,它可能是一个版本或系统依赖的缺陷/不是真正意图的行为。用当前版本的QT再次尝试它会很有趣。
(我的规格:Windows 7 64位,Python 2.7.2 64位,PySide 1.2.1包装Qt 4.8)
答案 3 :(得分:1)
This is really just this question in disguise - 在https://bugreports.qt.io/browse/QTBUG-42331
上查看并投票简而言之,fitInView具有硬编码边距,这可能会造成各种各样的破坏 - 其中最少的是现在你丢失了几个像素的显示区域,也可能会强制进行不必要的重新缩放。
PS。确保选择答案
答案 4 :(得分:0)
我修复了它创建我自己的fitInView()方法。它与原始QGraphicView方法基本相同,但边距除外:
void MyClass::fitInView_fixed(const QRectF &rect, Qt::AspectRatioMode aspectRatioMode)
{
if (!scene() || rect.isNull())
return;
auto unity = transform().mapRect(QRectF(0, 0, 1, 1));
if (unity.isEmpty())
return;
scale(1/unity.width(), 1/unity.height());
auto viewRect = viewport()->rect();
if (viewRect.isEmpty())
return;
auto sceneRect = transform().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(xratio, yratio);
centerOn(rect.center());
}