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?
Related
I have a QMainWindow with a center widget and a number of dockable widgets. The size of the various widgets get manipulated by the sliders between the dockables. I would like to fix the center widget's height to it's minimumSize height and not allow it to be made larger by the user. The width should remain relative to the QMainWindow (I only allow top and bottom dockables, so the center widget is stretched to the width of the main window).
The center widget is a QDockWidget, containing a QWidget with a QVBoxLayout (containing more stuff).
I have tried deriving from the QVBoxLayout and overriding maximumSize, but it wasn't respected. Overriding expandingDirections also didn't make any difference.
Any advise on how to achieve this?
Got it, thanks to Johannes Schaub.
I thought the QDockWidget propagates the constraints to its contained widget, which it does not. Setting maximumHeight on the inner Widget does the trick.
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
I have two widgets (both QFrames), none of them have any title bar associated with them (which I achieve through setWindowFlags(Qt::FramelessWindowHint)). One of them is a main widget, and the other a sidebar sort of widget, which is supposed to stick to it at its right boundary (its height being approximately 1/4th of the main widget).
I cannot keep them both in a transparent QFrame with static positioning, since the main widget is draggable through its top (since title bar is missing on it, I do it manually by intercepting mousepress/mousemove events and moving it accordingly). The custom drag on the main widget works fine, but when I try to move the sidebar along with, a very obvious visual delay shows up between the two, there are momentary gaps visible between the two while dragging the main widget to the left, or momentary overlapping between the two when dragging the main widget to the right (the sidebar is not draggable, no drag logic is implemented for it).
How do I 'glue' these two widgets together, such that they move together all the time without any delay? I browsed the Qt docs, it may be possible that QDockWidget can help here, but I could not understand how. The main widget here is not a QMainWindow.
Platform - OS X Yosemite, Qt 5.3.1, 32 bit.
You should definitely use QDockWidget here.
Make your "main widget" derive from QMainWindow rather than QFrame (it may not be "obvious" as QMainWindow does not derive from QFrame, but it should not be such a big deal).
Then, encapsulate your second widget within a QDockWidget and dock it in the main widget like that:
// secondWidget being your QFrame based widget
// mainWidget being your "main widget"
QDockWidget* dockingBar = new QDockWidget("My bar", mainWidget );
dockingBar->setWidget( secondWidget );
// dock on left side, change first parameter to dock somewhere else:
mainWidget->addDockWidget( Qt::LeftDockWidgetArea, dockingBar );
An alternative is to create a third widget that would become your top-level widget and use a QLayout to insert your two QFrames in this new one:
QWidget* newTopLevelWidget = new QWidget();
// QHBoxLayout to have mainWidget on the left hand side of secondWidget
// Replace by QVBoxLayout to have mainWidget on top of secondWidget
QLayout* layout = new QHBoxLayout( newTopLevelWidget );
layout->addWidget( mainWidget );
layout->addWidget( secondWidget );
i'm stuck with a simple Function of Qt that does not work for me.i made a class that inherits
from QMainWindow and another class that inherits from QWidget.then i made from the second a member object(a pointer to) inside the first and assigned it as its centralWidget during the construction of my window.
when it comes to adjust my centraWidget inside the window with the function QWidget::setGeomerty() it simply don't work.here's my code:
void MainWindow::show()
{
//some code that centers my window on the screen
int margin=this->width()/7;
centralWidget()->setGeometry(margin,centralWidget()->geometry().top(),this->width()-margin,centralWidget()->geometry().bottom());
QMainWindow::show();
}
i know it might be stupid but i just can't figure it out.help me.
QMainWindow has its own layout in which the center area is occupied by the central widget. So it won't be pretty straightforward to break that layout and modify the central widget size / position arbitrarily.
What I recommend is to use a placeholder central widget and add your widget as a child.
I'm pretty sure you can achieve what you want by setting a proper Qt built in layout to the "placeholder" central widget and then adding your widget to the layout.
layouts was necessary to manage what i want; i think it's not possible to hand directly over the central widget and try to move/resize it;but by adding a layout and a child widget, we can dispose of them.here is my code:
mainwindow.cpp
// i focused on my window constructor
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
m_MainView(new MainView(this)),
m_WindowLayout(new MainWindLayout(NULL))//my custom layout witch just inherits from QGridLayout
{
//.............
setCentralWidget(m_MainView);
m_WindowLayout=new MainWindLayout(m_MainView);//my layout set into my central Widget"m_MainView".
QWidget *temp(dynamic_cast<QWidget *>(m_MainView->centralView()));//centralView() returns a child QWidget of my central Widget
QMargins margins(this->width()/5,0,this->width()/5,0);//setting up layout margins :left,top,right,bottom;exactly what i need
m_WindowLayout->setContentsMargins( margins);
m_WindowLayout->addWidget(temp,0,0,-1,-1);//adding my child widget to the layout filling all cells of the gridlayout.
}
thanks everybody
I'm trying to write a map editor in Qt, using QGraphicsView and QGraphicsScene for both the map and tile sheets.
The problem I'm having right now is with making a good widget for importing tiles. For this, I'm using a QTabWidget (for different tile sheets), and TileWidget as the widget for each tab, which contains the QGraphicsScene and QGraphicsView.
It's working to a rough degree, but not all the tiles (or TileObjects, which are implementations of QGraphicsItem) are visible. I'm even calling view->ensureVisible(scene->sceneRect()), but still not all of the QGraphicsScene is not visible, even with scroll bars.
I understand this is due to limiting the maximum size of my QTabWidget, but that is necessary.
This happens mainly when I import a larger tile sheet.
I have a TileWidget as the QWidget for the QTabWidget, which has both the QGraphicsScene and the QGraphicsView.
TileWidget::TileWidget(QWidget *parent)
: QWidget(parent)
{
scene = new QGraphicsScene;
view = new TileView(scene, this);
connect(view, SIGNAL(newBrushSelected(TileObject *b)), this, SLOT(selectNewBrush(TileObject *b)));
}
TileView is simply a QGraphicsView re-implemented to handle mouse release events.
To add tiles, I simply call scene->addItem().
I have no other code for TileView. When I use
void TileWidget::showEvent(QShowEvent *event)
{
view->fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio);
}
I get something like this.
It's okay for smaller tile sheets, but not for larger ones. What should I add to keep the size of the tiles normal, and navigate TileView using scroll bars?
Nevermind, figured it out. Just me being stupid.
You need something like:
p_myGraphicsView->fitInView(
myGraphicsView->scene()->itemsBoundingRect(),
Qt::KeepAspectRatio);