Set a new layout on button - qt

I have a layout (containing QLabels and QSpacers) set on a button and I want to replace this with a new one. To do this I have made the following code:
while(!layout.isEmpty())
{
delete(layout.takeAt(0));
}
After this I set the new layout:
layout.addWidget(...)
layout.addSpacer(...)
...
button.setLayout(layout)
Unfortunately the new layout is set, but the old one can still be seen. How do I solve this?

Based on your comments, you want to delete the items in the widget, not the layout. QLayout::takeAt returns a QLayoutItem*. Thus, you are looping through the widget's layout and deleting the layout items, but not the widgets that were added to the layout items. As a test, you might try the following instead:
while(!layout.isEmpty())
{
delete layout.itemAt(0)->widget();
delete layout.takeAt(0);
}
However, this isn't what I would consider a good long-term design. There may be a few special cases where this is the best method, but I would recommend looking into using a stacked widget or something similar to switch back and forth between the widgets presented, rather than destroy and recreate a whole array of widgets in a button. Alternately, consider two different buttons, and destroy and reinsert just the button rather than the contents of the button.

You could try doing
delete button.layout();
before setting the new layout.
Alternatively, you can just add the widgets etc to the existing layout (and not set a new layout then).
[Edit]
As long as you only use a pointer on the old layout, this should work:
QLayout* layout = button.layout();
while( !layout->isEmpty() )
{
delete( layout->takeAt( 0 ) );
}
layout->addWidget(...)
layout->addSpacer(...)
// do not call button.setLayout()
[Edit2]
If this is only an update problem you can try
button->update();
QApplication::processEvents( QEventLoop::IgnoreUserInputEvents );

Related

How do you scroll a list in AppMaker?

I have a list widget with five rows per page. When the user goes to the next page I reload the page (by doing an unload/load on the data source with the new page number) and that works fine. However, the list stays scrolled to the bottom. How can I scroll the list to the top so the user does not have to?
I tried the ways that work in standard HTML but they do not work in AppMaker, and I cannot find any documentation on how to do this.
Thanks for any tips or pointers.
I realize this is an old post, but for future visitors, here's what worked for me - you need to set the index of the list to zero. App Maker ensures that it scrolls the last selected item into view, and maintains this across navigations.
You can do this by passing in a callback function that runs after loading the list. For me, I reload the list from a dropdown widget that filters the list, so in the onValueChange event I've added:
// Load datasource
widget.datasource.load(function() {
// Set index to 1 to ensure we scroll to top of list
app.datasources.YOURDATASOURCE.selectIndex(0);
});
You can achieve the desired behavior by doing the following:
In the outline, locate the TablePanel widget and select the List:TableBody widget
2.In the property editor, scroll to the Events section and click on the onDataLoad event value. Then click on Custom Action.
Type in this code var elem = widget.getElement(); elem.scrollTop = 0; so that it looks like this
Make sure the change is saved and then preview your app and it should work. Let me know if you need something else or if it don't work.
For me Morfinismo's answer didn't work, but the following did:
In the style editor add CSS for the List element:
.app-pageName-nameOfTheListWidget {
overflow-y: auto;
}
And in the Property Editor under Layout set a Max height.

Collapsing Toolbar Layout always expanded when returned from fragment

I have 2 fragments (Fragment A and Fragment B) both with collapsing toolbar layouts and corresponding recyclerviews within a coordinatorlayout.
If I scroll up in my recyclerview (so the CollapsingToolbarLayout has collapsed) and then open Fragment B from fragment A (Pushing A onto the backstack).
When I return to fragment A by hitting back. The CollapsingToolbarLayout/AppBarLayout is always expanded, even though the recycler view is in the same position.
Anyone experience this?
There's a issue related to this.
According to Chris Banes.
Add these lines inside onViewCreated() of your fragment to solve the issue.
ViewCompat.requestApplyInsets(mCoordinatorLayout);
It's an old question but none of the answers it's correct. I found this other question where they fixed the problem:
How to restore Collapsing Toolbar Layout State after screen orientation change
You have to set an id to your views in order to restore their state automatically.
I had face same problem so i write below code:-
private boolean isExpand = true;
private void setTitleNotExpand(boolean isExpand) {
if(getFragmentViewHolder() != null) {
this.isExpand = isExpand;
// AppBarLayout variable
getFragmentViewHolder().appbar.setExpanded(isExpand);
}
}
when you do add back stack then write below code :-
// write below code where you want to stick your toolbar
setTitleNotExpand(false);
// write below code where you want not to stick your toolbar
setTitleNotExpand(true);
on your onFragmentViewHolderCreated write below code :-
getFragmentViewHolder().appbar.setExpanded(isExpand);
another thing to consider is that views cannot restore their state if they don't have an id
Today, to fix this issue you only have to set an id to your coordinator layout to fix this.

Dojo grid goes hidden when grid is refreshed

I am refreshing dojox.grid.EnhancedGrid using dojo.data.ItemFileWriteStore per second. I have a dijit.layout.TabContainer where EnhancedGrid is present in one of the tab. When I switched the tab and come back to grid tab, the whole grid disappears.
What can be the solution?
var store = new dojo.data.ItemFileWriteStore({
url: '',
data: result,
urlPreventCache: false
});
grid.setStore(store);
I'm not sure about using EnhancedGrid but I had the same error when I used DataGrid to create a dynamic and changing matrix and this is how I was able to fix it.
Your problem arises because:
Your old structure property in the grid doesn't support the new store (different fieldnames etc.). If you don't get the structure right, Dojo complains and you don't see a grid.
I'm pretty sure it's this one. grid.setStore(newStore) doesn't work the second time probably because grid adapts itself to the first declaration of the store. I had tried the grid.setStore() and grid.setStructure() methods and it didn't show up after the first "refresh".
My solution:
Empty your container with dojo.empty() and create a new grid in that container every time you refresh with your new store

How can I get a hidden QGraphicsItem in a QGraphicsLayout to give up its space?

I have a QGraphicsLinearLayout with a series of QGraphicsWidgets within. I can hide the widgets just fine, but the layout spaces out all of the remaining widgets as if the hidden ones are still visible. How can I get the layout to use this space?
My code is something like this:
//scene is a QGraphicsScene*, myWidget# inherits QGraphicsWidget
scene->addItem(myWidget1);
layout->addItem(myWidget1);
scene->addItem(myWidget2);
layout->addItem(myWidget2)
scene->addItem(myWidget3);
layout->addItem(myWidget3)
//then later, I call
myWidget2->hide();
But although myWidget2 is now invisible, the layout is still spaced as though it were there. How can I change that?
Thanks.
Try calling QGraphicsLinearLayout::invalidate() to clear any cached geometry information after hiding the widget. If that doesn't help I would assume that removing the widget from the layout (if that is feasible for you) should do it.
I think you are loking for QWidget::findChild<T>(Qstring name)
name - an object name which can be set with QObject::setObjectName(Qstring name)
T - is a type of an object you are loking for.
so in your case code should look like:
MyWidget* myWidget1 = new MyWidget(this);
myWidget1->setObjectName("myWidget1");
........
MyWidget* requiredWidget=scene->findChild<MyWidget*>("myWidget1");

How print Flex components in FireFox3?

Thanks to FireFox's buggy implementation of ActiveX components (it really should take an image of them when printing) Flex components (in our case charts) don't print in FX.
They print fine in IE7, even IE6.
We need these charts to print, but they also have dynamic content. I don't really want to draw them again as images when the user prints - the Flex component should do it.
We've found a potential workaround, but unfortunately it doesn't work in FireFox3 (in FireFox2 it sort-of works, but not well enough).
Anyone know a workaround?
Using the ACPrintManager I was able to get firefox 3 to print perfectly!
The one thing I had to add to the example was to check if stage was null, and callLater if the stage was null.
private function initPrint():void {
//if we don't have a stage, wait until the next frame and try again
if ( stage == null ) {
callLater(initPrint);
return;
}
PrintManager.init(stage);
var data:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
data.draw(myDataGrid);
PrintManager.setPrintableContent(data);
}
Thanks. A load of callLater-s added to our custom chart code seems to have done it.

Resources