Creating a new top-level QML Window using createObject (null) - qt

I am working on a desktop application where I need the user to be able to "undock" certain elements of the GUI. I am currently achieving this by reparenting the element that needs to be undocked to the contentItem of a dynamically created ApplicationWindow. This works well but only if I pass null or undefined as the parent to the createObject() function like so:
var window_component = Qt.createComponent("Secondary_Window.qml")
var window_object = window_component.createObject(null, {section_name: section})
If I pass anything else to the createObject() function, like say the main window element or a child of the main window element, I get a window but I can not bring the main window in front of the new window by clicking on it. Nor are there tabs that appear in the Windows taskbar indicating that the application is currently using multiple Windows. The new window literally remains up front at all times until it is closed. So my question is: Is it good practice to dynamically create a new window in QML by calling window_component.createObject (null) or is there another way to achieve what I described above (by say passing a flag to the window)? I have been experimenting with different flag combinations but haven't yet found a combination that works. Also, the documentation of createObject() says that if you don't pass a parent as a parameter then the object will not be visible but that doesn't seem to be the case here. The window is displaying just fine.

A parent is a defined concept for Items.
A Window is not an Item so specifying null is not only ok but appropriate.

Related

Render a QQuickItem on a second window without changing its parent hierarchy

I have to render a QQuickItem owned by a particular window, into another. Basically MyQQuickItem owned by window1 to be rendered on window2. This switch has to happen in my app repeatedly due to a certain functionality.
I do the following to achieve the goal & the code basically works fine.
Code:
MyQQuickItem * myQuickItem = qmlEngine->rootObjects()[0]->findChild<QQuickItem*>("myquickitemobject");
myQuickItem->setParentItem(window1->contentItem());
// do the required on window2
// then set window1 as parent back again
myQuickItem->setParentItem(window2->contentItem());
Problem:
Above technique functionally works fine. But this requires me to flip flop a few times juggling between setting parent item from window1 to window2 & back again.
Question:
Is there some other way to share MyQQuickItem between the 2 windows? Or is it possible display MyQQuickItem on the both the windows alternatively without having to change the parent hierarchy?
You might use grabToImage() and display the grabbed image on your second window.
This might not be ideal, performance wise. You can find some questions on how to do this on this site. Especially interesting might be this.
I don't know your case, but it might be better, to have two instances of the same component displaying the same data model - possible with input for one disabled.

How to completely initialise a component but not add it to the display? Flex

I need to completely initialize a custom component in my Flex app (i.e. I should be able to access it from action script and get its properties and its children etc), But I do not want to add it to the display or make it visible.
I have tried to add it to my visible component, but keep it visible, but often many of its properties are set only when it is drawn, so i don't get what i need.
Is there a way to add a custom component to some sort of 'Virtual' display, that is not visible to the user?
You could add the component to an invisible Sprite - that way the component itself could both be on the stage and have its own visible property set to true.
Did you try using initialize()? After a view is added to the display list, the initialization stage begins. Calling initialize() before addChild() should let you initialize the view without needing to first add it to the stage.
For more info visit:
http://flexscript.wordpress.com/2008/10/24/flex-component-lifecycle-and-flex-component-framework/
http://blog.deadinkvinyl.com/2008/10/05/flex-3-addchild-and-initialize/
Not sure if possible without adding it to the display list, although I'd wish it were to some extent.
I once had to make custom drag proxy, which didn't work with the real component, because of some weird skinning issues. So instead I had PopupMananger add a box as a popup, added my component to the box, called validateNow on the component, drew it in a bitmap data, removed the popup, and used the bitmap data as the proxy.
So what you were trying was missing a call to validateNow most likely.

How to update a QLayout and get the new dimensions before returning?

This is driving me nuts. I have a custom menu class that, when set visible, shows a list of items located in a particular folder. When a hardware button is pressed, my application gets the latest list of items, populates the menu with them, and returns.
The menu displaying these items uses a QListWidget filled with custom widgets. Each of the widgets contains one or more QLabels in a horizontal layout, and is created at the time the menu is shown. In order to adjust the text displayed based on the menu width available, I need to get the size of the QLabel AFTER it has been resized according to the layout, but before the menu becomes visible to the user. The problem is, my layout does not get updated until all of the functions constructing my list return.
I have tried QApplication::ProcessEvents() and the layout update functions, but none of them have updated the values of my QLabels before returning. I can set a QTimer when the button is initially pressed, and have it show the menu, update the items, and stop itself, but that seems like a terrible solution.
Any help would really be appreciated! I've spent most of a day on this.
Marlon
I had this exact problem and could not find an answer anywhere on the Internet. Calling Layout.update(), Layout.activate(), or widget.adjustSize() (all suggested in various places) all did not work.
I had a widget with a vertical layout that I wanted to add a QLabel to and then immediately use the size of the QLabel.
The only thing that worked reliably was
layout->addWidget(myLabel);
myLabel->show();
size = myLabel->size();
It would seem that layouts will just not recalculate until you either return from a function and allow the Qt event loop to progress or manually call show() yourself.
How to update a QLayout and get the new dimensions before returning?
Don't. You're not meant to do that. It'll drive you "nuts" because you're doing it backwards. Layout updates are handled asynchronously from the event loop. Instead of getting layout dimensions right away, set yourself up to be part of the system. Some options are:
Implement a custom widget that will interact properly with the layout, growing to fill the available width of the layout. Perhaps all you need is a size policy and a way to elide text?
Make a custom layout that takes the special properties of your use case into account.
You want to call QWidget::adjustSize() on your parent widget. This will force the layout recalculations.
Have you tried using layout()->update(); ?
I've tried many but nothing works for me on Qt 5.15.
Only invented little patch - create timer and get size after 20 msec:
QTimer::singleShot(20, this, [this]
{
const auto height = myLayout->contentsRect().height();
// ...
});

Straightforward way to count number of windows up through PopUpManager?

I'm using the PopUpManager to bring a bunch of event windows up.
I want to make it so that only one window can be open at a time, but I don't see anywhere in the code that tracks open windows to set up a conditional. I guess it just creates the windows and then sets them free?
Thinking about a windowCount variable that increments when I add a window and decrements when I remove one, but since the PopupManager is called in different classes I'd have to start throwing events all over the place. I can do that, but I'm wondering if there's a more straightforward method?
The systemManager (rather than PopUpManager, go figure...) provides information on the currently opened popup windows.
If your popups are all model then you will be interested in 'systemManager.numModalWindows':
The number of modal windows. Modal
windows don't allow clicking in
another windows which would normally
activate the FocusManager in that
window. The PopUpManager modifies this
count as it creates and destroys modal
windows.
Otherwise try out 'systemManager.popUpChildren':
An list of the topMost (popup) windows
being parented by this ISystemManager.
An ISystemManager has various types of
children, such as the Application,
popups, tooltips, and custom cursors.
You can access the top-most windows
through the popUpChildren property.
The IChildList object has methods like
getChildAt() and properties like
numChildren. For example,
popUpChildren.numChildren gives the
number of topmost windows and you can
access them as
popUpChildren.getChildAt(i).
I see a few options:
1) Make all your windows modal; so that the application can't be used until the window is closed. This is a argument to the createPopUp method on the PopUpManager. Presumably you do not have Popups creating other popups.
2) Create your own Manager class, possibly an extension of the PopUpManager class that keeps track of all open windows. Then you'd have a single source of all PopUps and could maintain them that way.

Debugging or Watching Static Variables within Flash Builder 4

Problem:
When I set a breakpoint and debug my application, Flash Builder 4 is not displaying static variables within the variables window. I can't seem to find a solution in other posts.
More detail:
I'm using flash builder 4 to execute flex unit tests on one of my AS3 classes. I set a static variable within the [Before] function, which is accessed in each of the tests.
I've set a breakpoint within one of the tests to see why it is failing, but I notice that static variables don't appear when I expand the 'this' object within the variables window.
(In this case my static variable is the only variable associated with the class, so the only object in the variables window is the "this" object).
Question:
Does anybody know how to make static variables appear in the variables window?
Thanks,
Cookie
True, the Variables panel only shows non-static variables in scope.
BUT, you can use the Expressions panel to keep an eye on those static variables... even if they are private. Just type YourClass.staticVariable into a new Expression row, and it will watch your statics for you no problem at all.
You can also hover your mouse over the static variable and a tooltip will appear with the value.
Just for fun, I compared it to Visual Studio. The comparable panel is called "Locals" over there, and it DOES let you see static members while looking at instances... so, using VS as a precedent, you are not out of line for thinking that you might be able to do this in FB. But alas, use "Expressions" instead.
:)
There's a filter for the variables view that determines what you'll see. On the top right of the variables panel is a menu button (the icon is an upside down triangle), click that, choose Flex from the drop-down and select 'Show Inaccessible Member Variables'.
Cheers!
I'm on Flash Builder 4.7 and none of the answers given by K0j0 and Brian Genisio applies. So far the only way I can debug a static variable is by assigning it to a local variable (thus had to modify the code). Hope there's a better way of doing this somehow

Resources