QScrollArea widgets and layouts - PySide/PyQt - pyqt

I've read endless examples on nullege, as well as previous questions on this topic on SO. I'm thoroughly confused with trying to set up a QScrollArea within my PySide UI project. Here's what I'm trying to achieve:
A QWidget or QFrame which acts as a container on a page.
The QWidget/QFrame contains 8 Pixmapped labels.
Only 2 of the Pixmapped labels can 'fit' within the visible part of the screen at a time.
A QScrollArea is utilised such that the entire range of the QWidget/QFrame can be seen, using the horizontal scroll bars.
In theory this is really quite simple, but I just can't figure out how the QScrollArea links with the QWidget/QFrame, and whether I need a QLayout as well. At the moment, the horizontal scroll bars are present, but scrolling is unavailable. Here's what I have so far:
#Oscar Home Scroll Area - Scroll Area#
self.ScrollAreaOscarHome = QtGui.QScrollArea(self)
self.ScrollAreaOscarHome.setGeometry(QtCore.QRect(12, 180, 1000, 570))
self.ScrollAreaOscarHome.setVisible(True)
self.ScrollAreaOscarHome.setFrameShape(QtGui.QFrame.NoFrame)
self.ScrollAreaOscarHome.setObjectName("ScrollAreaOscarHome")
self.ScrollAreaOscarHome.setWidgetResizable(True)
self.ScrollAreaOscarHome.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.ScrollAreaOscarHome.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
#Oscar Home Container Widget - Widget#
self.WidgetOscarHomeContainer = QtGui.QWidget()
self.WidgetOscarHomeContainer.setGeometry(QtCore.QRect(12, 180, 2000, 570))
self.WidgetOscarHomeContainer.setObjectName("WidgetOscarHomeContainer")
self.ScrollAreaOscarHome.setWidget(self.WidgetOscarHomeContainer)
#Oscar Home Horizontal Layout - QHBoxLayout#
self.OscarHomeHorizontalLayout = QtGui.QHBoxLayout(self.WidgetOscarHomeContainer)
I've included the QHBoxLayout section above because previous examples I've read used the Layout, but I'm not sure how it fits in to the Widget and the ScrollArea.
Am I on the right track here? I'm not getting any errors, and the ScrollArea is displaying as I'd like, but the ScrollArea and Widget (which is much wider than the ScrollArea) don't seem to be linked at all.
Any guidance would be greatly appreciated!

Related

Qt Designer make widget overlap another widget in layout

I want to make 3 window button like above picture (similar Google Chrome) use Qt Designer and PyQt.
I want 3 buttons overlap right side of TabWidget.
But I only can overlap the Button on TabWidget when break layout like the picture.
When I set any layout, every widget can not overlap on each other.
So can I overlap when set layout? Thanks.
This is the layout I want
It similar Google Chrome's layout
This cannot be done in creator/designer, and can only be achieved using setCornerWidget() from your code.
Since only one widget can be set for each corner, you have to create a QWidget that acts as a container, then add the buttons to it.
class Test(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
# ...
self.createButtons()
def createButtons(self):
# create the container and its layout
self.buttonContainer = QtWidgets.QWidget()
buttonLayout = QtWidgets.QHBoxLayout(self.buttonContainer)
# remove margins around the layout and set a minimal spacing between
# the children widgets
buttonLayout.setContentsMargins(0, 0, 0, 0)
buttonLayout.setSpacing(1)
# QToolButtons are usually better for this, as QPushButtons tend
# to expand themselves
self.minimizeButton = QtWidgets.QToolButton(text='_')
self.maximizeButton = QtWidgets.QToolButton(text='o')
self.closeButton = QtWidgets.QToolButton(text='x')
buttonLayout.addWidget(self.minimizeButton)
buttonLayout.addWidget(self.maximizeButton)
buttonLayout.addWidget(self.closeButton)
# set the container as the corner widget; as the docs explain,
# despite using "TopRightCorner", only the horizontal element (right
# in this case) will be used
self.tabWidget.setCornerWidget(
self.buttonContainer, QtCore.Qt.TopRightCorner)

Can't get buttons in custom layout to return a minimal width measurement with WRAP_CONTENT

I created a custom flow layout class to lay out a series of buttons of equal height and various widths depending on what text each button displays. Each row contains as many buttons as possible, and any remaining space is distributed evenly to fill up the row. This generally works, but I can't get the buttons to be just small enough to fit their text, and as a result most of the buttons are exactly the same size.
This is how I'm creating the button and adding it to the flow:
Button button = new Button(this);
button.setMinimumWidth(0);
button.setText(eventType.get("name").asString());
button.setAllCaps(false);
button.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
button.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
eventTypeFlow.addView(button);
In the layout class' onLayout, I measure each button like this:
View child = getChildAt(childIndex);
measureChild(child, MeasureSpec.makeMeasureSpec(clientWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(clientHeight, MeasureSpec.AT_MOST));
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
But unless the text in the button is especially long, the width is always the same (264 in my case). I tried creating a linear layout XML with the button in it, setting minimum width to 0 and layout:width to wrap_content and that way the button is smaller, but when I distribute the extra space the linear layout grows, not the button.
Is there a way to get the buttons to return a smaller measurement when adding them directly to the custom layout?
Try using a LinearLayout using the layout_weight attribute. Give each button equal weight (1) and set your android:width attribute to 0dp.
Linear Layout layout_weight
More on LinearLayout's LayoutParams can be found here.
What ended up working is inflating the same linear layout XML I described in my question, then removing the button from the linear layout and adding it directly to my custom layout. Not very elegant, but it's the only thing I found that gets those buttons to be smaller.

Resizing a custom XYChart in an FXML Tab Pane

This question related to Java-FX and its charting capabilities and resizing.
My problem is that I wanted to create a custom candlestick chart and I managed to get that done by going through the Ensemble application source code which was quite helpful.
The code for generating the candlestick is here:
http://javafx-ui-hxzon.googlecode.com/svn-history/r13/trunk/ChartsSampler/chartssampler/CandleStickChart.java
However, when I run my application, I seem to be stuck with a chart size that is fixed and does not resize according to my Tab Pane (the parent) resizing in my GUI. I've gone through the code, fiddled with it, changed the value of the minWidth and minHeight to USE_PREF_WIDTH AND USE_COMPUTE_WIDTH both but I cannot get it to fit to the parent Tab pane.
What am I missing?
I call AdvCandleStickChartSample in my controller as follows:
AdvCandleStickChartSample adv=new AdvCandleStickChartSample();
candleTab.setContent(adv);//candleTab has been predefined in an FXML file
My guess is I need to resize based on an event-handler? Am I correct in assuming this? Or am I not overriding a specific method that handles the resizing? When I create a dummy linechart and fill it with data and "run" it, it resizes fine along with the window.
Please help!
Never mind.
I found the answer. I simply had to override the layoutChildren() method by implementing the Pane superclass.
In the Ensemble application they accomplish this by implementing a "Sample" class which overrides the Pane super-class's layoutChildren() method

ExtJS 3.4 EditorGridPanel Layout Issues

GridPanel not rendering correctly
I'm using EditorGridPanels on dynamically generated web pages. ExtJS does not control the ViewPort.
When I wrap the Grid generation code in Ext.onReady(), the grids render perfectly.
If I do not wrap it in Ext.onReady() it renders with subtle layout issues like
the grids are a little too wide
the top toolbar gets cut off on the right
the rows don't quite fit and they shift when clicking a cell
I have tried forcing the grids' layout to get recalculated once the page loads...
(function(){}
var grid = ...
[ ... ]
Ext.onReady(function(){
grid.doLayout();
});
)();
...but this does not work.
The reason I'm trying to avoid placing Grid initialization inside Ext.onReady() is that sometimes pages take a long time to fully load every resource, and in these cases the pages look fully loaded apart from the blank spaces where the grids eventually get rendered to!
Any suggestions on what I might try? Right now a complete redesign of the page is not in scope, so I'm looking for something I can do to get the grid to layout like it does when initialized inside onReady()!
Thanks
You could perhaps mask the page initially with 'loading..' message and remove this in the onReady().
If you're getting issue outside of on the onReady it would indicate something has not loaded when you're trying to render components, this in my experience will lead to further issues down the line.

Menu on a EnhancedGrid behaves weird when the container takes 100% width and height

I've spent some time simplifying the code to get a simple example of the problem. I'm using Dojo 1.6.1. I've a TabContainer defined on my page. Dinamically, I add to it two tabs, each one of them contains an EnhancedGrid with a rowMenu(right click). The issue is that the menu does not work correctly on IE8 if the TabContainer is defined to use all the space available on the page. If I use a specific height and width, it works fine. By not working correctly I mean the following: The menu is pretty simple; it has just two MenuItem, one of them is a PopupMenu that shows a submenu, as follows:
If the TabContainer takes all the available width and height, the menu does something very strange. First, if you do a right click over a row, it does not do anything. You need to a second right click. Then the menu shows, but when you open the submenu, the main menu disapears, and the submenu does not work. It keeps floating around until you navigate to other page:
When it fails, it throws a javascript error saying "'undefined' is null or not an object", on the line 208 of dojox/grid/_FocusManager.js
[...]
_scrollHeader: function(currentIdx){
var info = null;
if(this._colHeadNode){
var cell = this.grid.getCell(currentIdx);
info = this._scrollInfo(cell, cell.getNode(0));
}
[...]
I've tried to create a jsfiddle sample, but Dojo 1.6.1 is not available there, and with Dojo .1.6.0 the behaviour is diferent (You need to do a left click on the row and then a right click, and then the menu works fine), so I've created a simple HTML sample you can see on http://pastebin.com/jDNFQxrP. To see the difference you just need to change the commented TabContainer at the bottom of the code. Has someone seen this before?
Thanks
JL

Resources