How to re-enable the background of QGraphicsView's child widgets? - c++

When adding QWidgets such as QGroupBox and QFrame to a layout set on QGraphicsView, those widgets have no background. Various things that seem like they should re-enable it, do not work. (E.g., setAutoFillBackground(true);.)
Is there some way to get the widgets to draw their background again?
QFrame* mycw = new QFrame();
QHBoxLayout* loMain = new QHBoxLayout();
loMain->addWidget( mycw );
pView = new QGraphicsView();
pView->setLayout( loMain );
pView->showFullscreen();
Edit: This may have something to do with opengl or something. I have tried to work around it, by making the two widgets peers - and using the resizeEvent of the parent to arrange them with no layout at all. And it still happens! If it's drawn in-front of the QGraphicsView, it ends up with no background.
I will have to dig deeper. :(

If you want to apply a background color on a widget you can use maybe:
widget->setStyleSheet("background-color: yellow");

Related

Qt How to change stylesheet of the widgetContents-widget of every scrollarea in mainWindow?

In Qt I can not just style the QScrollArea (I only want to set the background color), I have to style the widgetContents-widget of every scrollarea like:
// qss code
QScrollArea #scrollAreaWidgetContents_1, #scrollAreaWidgetContents_2, ...{
background-color: MYCOLOR;
}
Question: How do I have to set up the stylesheet of mainWindow, that the widgetContents-widget of every scrollarea changes its background color without calling them all manually like in the example? Thanks for answers!
If you don't use the widget's object names somewhere else, you could set a common object name for all of them:
auto* content = new QWidget();
content->setObjectName("scrollAreaWidget");
auto* scrollArea = new QScrollArea();
scrollArea->setWidget(content);
And then address them from the qss like this:
QWidget#scrollAreaWidget
{
background-color: white;
}
If that is no option, you can try subclassing QWidget and apply the style for your new class. I haven't tried this approach, but it seems, you might face some difficulties there.

In QT "ui->scrollArea->horizontalScrollBar()->setValue(0)" has no effect

So in my UI designer I have a ScrollArea Widget, I then in my MainWindow.cpp, I create a QGraphicScene and a QGraphics View. I create a new widget and give that widget a QVBoxLayout so that it will auto-size(which is correct to my understanding).
I then use ui->scrollArea->setWidget(widget); to make this new widget the child of my scrollView.
All of this seems correct because I have scroll bars that I can navigate my scene with. However; using the line ui->scrollArea->horizontalScrollBar()->setValue(0); still has no effect on the scroll bar values.
scene = new QGraphicsScene();
scene->setSceneRect(0,0,2500,2500);
view = new QGraphicsView(scene);
QWidget *widget = new QWidget;
view->setBackgroundBrush(Qt::white);
QVBoxLayout* bLayout = new QVBoxLayout(widget);
ui->scrollArea->setWidget(widget);
bLayout->addWidget(view);
widget->show();
ui->scrollArea->horizontalScrollBar()->setValue(0);
ui->scrollArea->verticalScrollBar()->setValue(0);
I just had the this problem. Then, after debugging with ui->scrollArea->verticalScrollBar()->value() I realized that the scrolling area has no size before the component is show on the screen, i.e., it does not change the scrolling because it is not visible yet.
This is a sample Python code, but the is the same for C++, except the Language Syntax.
from PyQt5.QtWidgets import QDialog
...
dialog = QDialog()
...
verticalScrollBar = dialog.QPlainTextEdit.verticalScrollBar()
horizontalScrollBar = dialog.QPlainTextEdit.horizontalScrollBar()
# Has no effect, if you print the values, you will see always 0
verticalScrollBar.setValue( horizontalScrollBar.maximum() )
horizontalScrollBar.setValue( horizontalScrollBar.minimum() )
dialog.show()
# Now it has effect
verticalScrollBar.setValue( horizontalScrollBar.maximum() )
horizontalScrollBar.setValue( horizontalScrollBar.minimum() )
Autoscroll PyQT QTextWidget
If you are sure to address the correct scrollbar (as pointed in the comments by thuga), maybe check if your scroll area is modified after that init. I mean I'm not sure of the bahaviour, but if you modified some text in your widget for example, I think the scrollbar will be impacted.
You may need to catch some of your widget's event to reapply those:
ui->scrollArea->horizontalScrollBar()->setValue(0);
ui->scrollArea->verticalScrollBar()->setValue(0);
If it doesn't help, you should try to debug by tracking scrollbar value with
ui->scrollArea->verticalScrollBar()->value()
and see if your set is well applied, and maybe when it is overriden
Just in case, you may also try some of the methods indicated here, but it's probably not relevant to your issue: setValue of ScrollBar Don't work at first time

QPaintEvent painting region in Qt?

This is a basic doubt regarding the Painting done in Qt.
I have a QScrollArea as my centralWidget in Main Window of my Application. I have added a QFrame frame to the scrollarea. The Layout of the QFrame is QGridLayout.
When I add widgets to the layout like this:
MainWindow::AddLabel()
{
setUpdatesEnabled(false);
QGridLayout *myGrid = (QGridLayout *)ui->frame->layout();
for(int i = 0; i < 1000; i++)
{
QLabel *label = new QLabel();
QString str;
str.SetNum(i);
label->SetText(str);
myGrid->AddWidget(label, 0, i, 0);//add label to i'th column of row 0
}
setUpdatesEnabled(true);
repaint();
}
Please dont worry about the memory leak as it is not the focus of the question.
So my doubt's are:
Is setting the updates disabled during adding widgets to layout any helpful?
Even if I maximise the window not all the QLabel's will be visible to me. So when the code flow leaves the above function & goes to the event loop then are all the QLabel's & the enormous area of QFrame painted? Or only those QLabel's which are visible & only that much area of QFrame which is visible painted?
If you are using a form (.ui) then the widgets inside the ui are not children of your widget MainWindow. Well , setUpdatesEnabled() only affect the current widget as well as its children, so the object ui->frame will still receive updates after myGrid->AddWidget. Change to
ui->frame->setUpdatesEnabled(false);
...
ui->frame->setUpdatesEnabled(true);
Btw, when you enable updates, then screen will be updated. So you dont need to call repaint(); on any widget.

QMainWindow centralWidget border

I have a QMainWindow whose central widget has been set to a QGraphicsView viewing a black scene (for test purposes). Note that in the code below, I use my class derived from QGraphicsView, called CQtGlView, which reimplements only the resizeEvent function.
Regardless of whether I add the view directly,
CQtMainWindow::CQtMainWindow() {
m_glView = new CQtGlView();
setCentralWidget(m_glView);
}
or stick it in a layout with margins of 0 in a dummy widget,
CQtMainWindow::CQtMainWindow() {
m_glView = new CQtGlView();
QWidget* dummy = new QWidget();
QHBoxLayout* l = new QHBoxLayout();
l->setContentsMargins(0,0,0,0);
l->addWidget(m_glView);
dummy->setLayout(l);
setCentralWidget(dummy);
}
I get an unwanted grey border around the widget.
The screenshot below illustrates the problem, visible between my scene and the windows aero border.
This would not be a problem if my application did not allow switching to full screen. The border is very obvious once the rest of the screen is black.
It's possible this area represents the DockWidgetAreas around the outside of the central widget.
Is there anything I can do to solve this other than not use QMainWindow? (Undesirable due to my use of menuBar, tool bars, and statusBar.)
It turns out that QGraphicsView derives from QFrame, where I assumed it was only a QWidget.
The solution to this problem was to call setFrameStyle(QFrame::NoFrame); in the constructor of my QGraphicsView subclass. Or if it was not a subclass,
m_glView->setFrameStyle(QFrame::NoFrame);
Have you tried setFrameShape(QFrame::NoFrame) on the QGraphicsView?

Qt Gridlayout doesn't realign GUI elements

I have the following code in the ctor of my main window widget, in my Qt App. No matter how I align the buttons added to the QGridLayout, they always stay in the upper left corner, on top of each other.
Can anybody tell me what I've done wrong, I can't find it.
btn_File= new QPushButton("&File", this);
btn_Close = new QPushButton("&Close", this);
btn_File->setAutoFillBackground(true);
btn_Close->setAutoFillBackground(true);
QGridLayout * layout = new QGridLayout(this);
layout->setContentsMargins(20,20,10,10);
layout->setSpacing(5);
layout->addWidget(btn_File,2,2, Qt::AlignRight);
layout->addWidget(btn_Close,1,1);
this->setLayout(layout);
EDIT: It seems that only the btn_Close is being drawn. I just tried to add a QComboBox to the grid, and it doesn't show up.
The problem was that my main window was derived from QMainWindow, in which you need to add a CentralWidget before adding GUI elements. I changed my main window to derive from QWidget instead, and now it works.
tried calling this->adjustSize() at the end?
qt layouts really suck!
alignment on qgridlayout depends on the size of the objects, how many cols an object needs, and the size of the biggest object inserted.. so it is very difficult to put objects as you want...
i suggest to use setGeometry or move instead!