示例代码来自我的项目。我试图尽可能地缩短它。
叠加层用于绘制应用中的所有其他小部件。这适用于大多数小部件,但今天我开始注意到QAbstractScrollArea子类给了我一些困难。问题是叠加层不会显示在顶部,并且阻止发生的任何绘图。
#include <QtGui/QApplication>
#include <QtGui/QVBoxLayout>
#include <QtGui/QGraphicsView>
#include <QtGui/QPushButton>
class View : public QGraphicsView{
public:
View(){
//delete viewport(); setViewport(new QWidget);
}
};
class Widget : public QWidget{
QWidget* overlay_;
public:
Widget(){
resize(512, 512);
QVBoxLayout* layout = new QVBoxLayout;
QPushButton* button = new QPushButton(" Click Me! ");
layout->addWidget(button);
layout->addWidget(new View);
overlay_ = new QWidget(this);
overlay_->installEventFilter(this);
connect(button, SIGNAL(clicked()),
overlay_, SLOT(show()));
overlay_->hide();
setLayout(layout);
}
bool eventFilter(QObject* target, QEvent* event){
if(target == overlay_){
if(event->type() == QEvent::Paint && overlay_->isVisible()){
overlay_->resize(size());
QPainter painter(overlay_);
painter.setPen(QPen(QColor(1, 102, 192, 255), 1, Qt::SolidLine,
Qt::FlatCap, Qt::MiterJoin));
painter.drawRect(rect().adjusted(60, 0, -60, 0));
return true;
}
}
}
};
int main(int argc, char *argv[]){
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
要在此示例中修复此问题并将叠加层置于View之上,您需要取消注释顶部的注释行。所以我的问题是这样的:为什么我需要在构造函数中删除并分配一个新的视口小部件,以便覆盖不被透支?
答案 0 :(得分:3)
这不是QGraphicsView的错误,如果您使用标准的QScrollArea也会发生错误。
我认为,问题在于Qt绘制子窗口小部件的顺序。同级小部件按照它们添加到父级的顺序绘制(尽管您不能依赖它)。
重置视口“解决”问题的原因是,当您这样做时,您创建一个没有背景的新QWidget作为视口。 QGraphicsView仍然在overlay_上绘制,它只有一个透明的视口。但请注意它仍然是在按钮后面绘制的。
如果只想在QGraphicsView上绘制叠加层,可以覆盖QGraphicsView :: paintEvent()并在那里进行。如果你想在整个小部件上绘制叠加层,我会将你的布局嵌入到第二个QWidget中,然后尝试使用QWidget :: raise()将叠加层强制显示在顶部。