I have an QMdiSubWindow which contains a couple of widgets. One of these widgets is a QWidget with a QGridLayout() which can contain an arbitrary number of sub-widgets which is determined at runtime (initially none). I can't seem to workout how to get the MDISubWindow to automatically resize when the number of sub-widgets in the grid layout changes. Should I be re-implementing the sizeHint() somewhere? ie in the main widget or the sub-widgets?
The QMdiSubWindow resizes fine when I drag the resize handle with the mouse and snaps to show the correct size.
I've tried calling .resize() and .updateGeometry() on both the widget and the QMdiSubWindow but It doesn't obviously work. Any clues would be much appreciated.
#ekhumoro suggested I try adjustSize(), which didn't work initially. I did some more searching and ended up with the following solution which worked for me
QTimer.singleShot(1, self.parent.windows[self.uuid].adjustSize)
where
self.parent.windows[self.uuid]
is the QMdiSubWindow object. I'm guessing that just calling self.adjustSize() doesn't work because the sizeHint is not updated until the later in the event queue.
Related
I have created a subclass of QDialog in PyQt5 and then set a QFormLayout as its layout.
Each row of the layout is defined similar to the following (simplified):
layout.addRow(QLineEdit(), QPushButton('Push Me'))
I have set the dialog to fixed height, but if I stretch the dialog horizontally, the button gets wider and the line edit stays the same width. What I want is for the line edit to get wider and the button size to remain unchanged. I have tried setting size policy for the button, but apparently QFormLayout ignores this. I have also tried making each row of the form layout a QHBoxLayout which contains the line edit and button; this did not work either. Does anyone have a solution to this problem? I really need for the button to remain on the right had side of the form.
How would I go about making a overlay widget with qt?
I've considered using a QPaintEvent or a QGraphicsScene, but I want to be able to add widgets and for the widget to not occupy space in a layout, causing other widgets to shift when the popup appears.
I believe the best solution is to parent the so called overlay widget to the window or even have the overlay widget be in its own window.
The first solution might be easier to do, but the overlay widget is bound to the inside of the window.
If you go with the second solution, you will have to play with the windows flags to make it borderless.
In both cases, you may have to use the raise() function to make sure your overlay widget is on top.
Discussing "using a QPaintEvent or a QGraphicsScene" is off-topic. How you draw the widget does not impact how the widget will interact with the widget stack.
If you want an example, you can take a look at the code of QCompleter which does something similar. In particular look for QCompleter::setPopup() and QCompleterPrivate::showPopup().
I just started with PyQt and I'm trying to sort elements in a QGridLayout. In the code below, I'm moving an existing button from the cell (4,1) to (0,0). My confusion arises because either using removeWidget or not, both pieces of code behave exactly the same:
myButton = self.myGridLayout.itemAtPosition(4, 1).widget()
self.myGridLayout.removeWidget(myButton)
self.myGridLayout.addWidget(myButton, 0, 0)
is the same as:
myButton = self.myGridLayout.itemAtPosition(4, 1).widget()
self.myGridLayout.addWidget(myButton, 0, 0)
Is PyQt handling everything behind the scenes or is there something that I have not noticed happening?
Thanks
A widget can only belong to one layout. Before a widget is added to a layout, Qt will check to see if it has ever been in a layout, and if so, it will remove it from whatever layout it currently belongs to. The widget will also be automatically reparented to the layout's current parent-widget.
A widget also cannot be added to the same layout twice - but that is really no different from the case above, and so it is treated in exactly the same way.
I've been having this issue a lot of times.
When I modify some properties of a QWidget after the widget.show(), the widget won't update. Most of the time, a mouse click or when the mouse leaves or enters the widget, the widget will be updated. However, if I leave the mouse, it won't refresh by itself.
Until now I managed to deal with this by doing :
widget.hide()
widget.show()
But this is a very dirty fix. Is there a better way to tell python to refresh the widget ?
Thank you.
To update the widget, you should repaint() it, but calling repaint() directly is not very good, so try:
widget.update()
From doc:
This function does not cause an immediate repaint; instead it
schedules a paint event for processing when Qt returns to the main
event loop. This permits Qt to optimize for more speed and less
flicker than a call to repaint() does.
Calling update() several times normally results in just one
paintEvent() call.
Qt normally erases the widget's area before the paintEvent() call. If
the Qt::WA_OpaquePaintEvent widget attribute is set, the widget is
responsible for painting all its pixels with an opaque color.
Did you already try the
QWidget.update()
This function updates only the visible parts keeping the invisible parts untouched.
I'm working on a X-plotter like widget that plots incomming data live.
I already searched for an solution to realize a scrolling along the x-axis if the widget has to much values and so they don't fit.
I had the folling approaches to realize it:
derive from a widget that supports scrolling and child widgets and add my own widget while making it bigger and bigger during the live updates: -> Which parent do I need to use and how do I avoid to draw all the stuff that is currently not visible?
modify my widget in a way that it supports the scrollbars itself -> but how?
draw/handle my own scrollbars -> worstcase :(
I really searched the web for suggestions or examples, but there is nothing about how to "construct" custom controls in a good way (beyond drawing something) esp. in the case of interaction...
Sorry but I'm a newbie at GTK in general :/
Most widgets in Gtk do not have scrollbars.
If you want to scroll the entire widget, you have to implement the GtkScrollable interface. Then, you add the widget to a GtkScrolledWindow. The scrolled window has the scrollbars, those GtkScrollbars are linked with GtkAdjustments which are passed to your custom widget through the GtkScrollable interface set_vadjustment and set_hadjustment.
If you just want to add a scrollbar and control its behaviour yourself, then you need to somehow add a GtkScrollbar in your widget, which means you will need to make it a container too.
The GtkScrollable approach is the following, first you implement vadjustment and hadjustment setters and getters, then when the GtkAdjustments are set, you set its lower and upper limits and the page size(how much of the widget is visible at once). After that, you connect their value-changed signal so you can refresh your widget when the scrollbars are dragged. A GtkScrollable doesn't get to check the scrollbars, only the adjustments that will be bound to the scrollbars. When drawing the widget you get the adjustments' value property in order to determine how much the scrollbars have shifted in the horizontal and vertical axes.