Does calling deleteLater() on a Qt object also deletes nested objects or not? For instance, I have a layout in which I add several widgets and layouts. Sometimes, I need to redraw or delete some layouts and/or widgets:
QWidget* blankWidget = new QWidget(this);
grid = new QGridLayout();
blankWidget->setLayout(grid);
setWidget(blankWidget);
QVBoxLayout* vBox = new QVBoxLayout();
realTimeCheckBox = new QCheckBox("Real Time Rendering", this);
vBox->addWidget(realTimeCheckBox);
grid->addLayout(vBox, 1, 0);
Is it safe to call in another method something like this?
grid->deleteLater();
Does it delete each nested layouts and widgets of the grid?
Update
Tested with the destroyed(QObject*) signal. As underlined in the comments, it works.
Related
how can add new control from controller
// create a simple Input field
var oInput1 = new sap.m.Text('input1');
oInput1.setText("Some Text ");
oInput1.setTooltip("This is a tooltip ");
// attach it to some element in the page
oInput1.placeAt("sample1");
in view I add holder
try to add text from controller but it not display on screen.
var oLayout = this.getView().byId("idholder");
oLayout.addContent(oInput1);
is Run-time add new control is not possible. we have always render control in view and then update it is this good practice we have to follow ?
The placeAt() method is normally only used to place a View or App into the HTML.
If you want to add a UI5 control on your view, you can do it this way from the controller:
this.getView().addContent(oInput1);
But most likely you won't add controls directly to the view, but rather inside a layout or something inside your view. In that case, do it like this:
var oLayout = this.getView().byId("idOfYourSpecificLayoutFrame");
oLayout.addContent(oInput1);
I'm working on a Kendo Mobile project with a number of:
Kendo Views (external to root html)
Modal Views (in the root html).
The external files load on demand and everything works fine. But i'd like to have the same load on demand behavior for some of the modal views, because the root/based html file is becoming too large and not manageable.
Is there a way to either:
Store a modal view in an external file? If so is it possible to load via javascript syntax (app.navigate()) rather than the declarative syntax (href='externalmodal').
Manually pre-load an external view without navigating to it first.
This code lets you manually create a view:
var viewUrl = 'blahblahblah';
var element = $.parseHTML('<div data-role=view>test</div>')[0];
element.style.display = 'none';
$(document.body).append(element);
var options = $.extend({}, kendo.parseOptions(element, kendo.mobile.ui.View.fn.options));
var view = new kendo.mobile.ui.View(element, options);
view.element[0].setAttribute('data-url', viewUrl);
kendo.mobile.application.navigate(viewUrl, '');
Depending on what features you use, you may need to instead use code similar that that used for ModalView below so that Kendo creates the subclass (changes: substitute View for ModalView, substitute view for modalview, add data-url, remove call to show(), maybe check that view not already created by checking for element with matching data-url). We haven't tested setting roles.view this way, but we did something similar while testing this stuff out and it worked.
Don't try settings the options - Kendo got confused (at least trying to set useNativeScrolling didn't work, also don't try setting the options object on the subclass unless you really know what you are doing).
Caveat: This was using browserHistory:false (which disables routing) when the kendo.mobile.Application was created. The technique should still work when using browser history if you use a valid url fragment (same as would be created by Kendo for the pushstate/hashchange url).
This is a also way to cleanly subclass kendo.mobile.ui.View that works well - although you must still use data-role=view even though your subclass is a "different" component. Note that you can't just use you cant use your own subclassed component with its own name like role=myview to subclass a view because there are hard-coded checks specifically for data-role=view in the kendo codebase. Same if you wish to subclass: layout modalview drawer splitview page (amongst other hard-coded kendo ui component names - search kendo code for kendo.roleSelector - ugly). e.g.
MyView = kendo.mobile.ui.View.extend({
init: function(element, options) {
kendo.mobile.ui.View.prototype.init.apply(this, arguments);
...
var myView = new MyView('<div data-role=view>test</div>');
Why it works: The relevant function in the Kendo source code is _findViewElement which does element = this.container.children("[" + attr("url") + "='" + urlPath + "']"); to see if the view already exists for a url, before creating a new one. A unique init function is always required as it ends up being the constructor function.
If you want to subclass a modalview, you need to do something different due to the way kendo works:
var MyModalView = kendo.mobile.ui.ModalView.extend({
html: '<div data-role=modalview style="width:90%;display:none;">Foobar</div>',
init: function() {
kendo.mobile.ui.ModalView.prototype.init.apply(this, arguments);
}
});
function makeModalView() {
$(document.body).append($.parseHTML(MyModalView.prototype.html));
var roles = $.extend({}, kendo.mobile.ui.roles);
roles.modalview = MyModalView;
var modalView = kendo.initWidget($(element), {}, roles);
modalView.open();
return modalView;
}
I am using the Alloy Diagram Builder to create and display network topology.
I would like to remove default click and drag events attached to each nodes, so viewers would not have the ability "build" diagrams but only view diagrams that I have generated.
http://alloyui.com/examples/diagram-builder/real-world/
I have tried these but it does not work.
// detach click event to all nodes with class aui-diagram-node.
Y.all('.aui-diagram-node').detach("click");
// unbind
$(".aui-diagram-node").each(function(){
$(this).unbind();
});
I believe the event is attached to the container .aui-diagram-builder-drop-container via delegate() and the event would be mousedown.
Merely by accident I found a hack that might work for this. I was adding tooltips to my page on which I had a diagram builder, well apparently the tooltips layer a div over the page and simply set the opacity on it to be clear and the object still resides. After a tooltip had come up i was unable to interact with the piece of the diagram builder the tooltip had popped up over.
So based of this concept, why not try overlaying a div over the entire canvas of the diagram and give it a high z-index so that it sits on top. It should effectively not allow interaction with the canvas.
Yes it's a kludge but it just may work.
To make a DiagramBuilder read-only, you can detach() events from all of its children recursively:
/*
* Readonly the diagram
*/
function ReadonlyDiagram(diagram) {
function detachRecursively(node) {
node.get('children').each(detachRecursively);
// You may also want to set the cursor to the default since it will
// change based on which elements the mouse is over.
// node.setStyle('cursor', 'auto');
// You may want to detach specific events such as 'click' or
// 'mousedown' if you do not want to disable all events.
node.detach();
};
diagram.on('render', function (event) {
detachRecursively(diagram.get('boundingBox'));
});
}
Now, you must be post diagramBuilder object to ReadonlyDiagram function like below codes:
YUI().use('aui-diagram-builder', function (y) {
var diagram = new y.DiagramBuilder(
{
availableFields: data,
boundingBox: '#' + containerId,
fields: nodes,
srcNode: '#' + builderId
}).render();
diagram.connectAll(connections);
if (callBackDiagram !== undefined) callBackDiagram(diagram);
if(isReadonly === true) ReadonlyDiagram(diagram);
});
});
Reference
This is my scenario:
many usercontrols, each of them contains many gridviews.
I want to (re)load a single gridview via an ajax call to get rid of postbacks and to improve performances and user experience.
I don't want to rewrite tons of code so I just want to render that single gridview of that single control. <br/>
It means that if the gridview shows 4 fields and it has a bound server method it must be executed picking the rules from the .ascx.cs and the .ascx.
I cannot create a new instance of a gridview cause i need it to get created based on the .ascx rules.
I used this piece of code to create the grid and put it into the textwriter.
System.Web.UI.WebControls.GridView grid = new System.Web.UI.WebControls.GridView();
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
using (HtmlTextWriter textWriter = new HtmlTextWriter(sw))
{
grid.DataSource = ds;
grid.DataBind();
grid.RenderControl(textWriter);
}
}
And it comes out like a normal grid as expected. But I don't need this; I need to generate a grid that is exactly the same as the one defined in the .ascx.
You should use an <asp:UpdatePanel>.
I'm using .net 2.0 with Visual Studio 2005 and I am trying to add two different toolstrips to the top of the form such that they show up side-by-side. I want it to be like Word 2003, where you can add multiple toolstrips to the same row and have them show up in line with each other, rather than dedicating a row to each toolstrip.
So I added a ToolStripPanel and docked it to the top of the form (I didn't use a ToolStripContainer because I don't need all the extra panels; I just need the one at the top). I added both toolstrips and set their Stretch properties to False. I can get them to show up in the designer window side-by-side, but at runtime the ToolStripPanel separates the toolstrips and gives each toolstrip its own dedicated row. As if to add insult to injury, when i stop debugging and return back to the designer, I am finding that the designer is moving the toolstrips to their own row as well! Am I doing something wrong here?
I have been Googling all day and found some information about a ToolStripPanelRow object, but I don't see an easy way to add toolstrips to it (i.e. it doesn't have a ToolStripPanelRow.Controls.Add method or anything like that), all it has is a Controls() property that returns an Array of control objects, and I haven't had much luck trying to add items to that array. I also found some documentation on the ToolStripPanel.Join method, which sounds like it should do the job, so I tried all 3 overloads but they don't work as advertised. No matter what I do or which options I try, it always adds the new toolstrip to the top of the panel on its own row and pushes everything else down.
In the interests of full disclosure I should warn you that I have the ToolStripPanel and one of the toolstrips added to a baseclass form, and I am trying to add the other toolstrip to a subclass form that inherits from the baseclass form. The ToolStripPanel and ToolStrip in the baseclass form are both declared "Protected Friend", so this should be working. As I mentioned, the subclass form's designer window will allow me to do it (at least, for a time).
If anyone can help me get this working or at least shed some light on why it isn't, I would be extremely grateful.
I created a custom ToolStripPanel so that I could overload the LayoutEngine;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Layout;
namespace CustomGUI
{
class CustomToolStripPanel : ToolStripPanel
{
private LayoutEngine _layoutEngine;
public override LayoutEngine LayoutEngine
{
get
{
if (_layoutEngine == null) _layoutEngine = new CustomLayoutEngine();
return _layoutEngine;
}
}
public override Size GetPreferredSize(Size proposedSize)
{
Size size = base.GetPreferredSize(proposedSize);
foreach(Control control in Controls)
{
int newHeight = control.Height + control.Margin.Vertical + Padding.Vertical;
if (newHeight > size.Height) size.Height = newHeight;
}
return size;
}
}
}
Then the custom LayoutEngine lays out the ToolStrips;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Layout;
namespace CustomGUI
{
class CustomLayoutEngine : LayoutEngine
{
public override bool Layout(object container, LayoutEventArgs layoutEventArgs)
{
Control parent = container as Control;
Rectangle parentDisplayRectangle = parent.DisplayRectangle;
Control [] source = new Control[parent.Controls.Count];
parent.Controls.CopyTo(source, 0);
Point nextControlLocation = parentDisplayRectangle.Location;
foreach (Control c in source)
{
if (!c.Visible) continue;
nextControlLocation.Offset(c.Margin.Left, c.Margin.Top);
c.Location = nextControlLocation;
if (c.AutoSize)
{
c.Size = c.GetPreferredSize(parentDisplayRectangle.Size);
}
nextControlLocation.Y = parentDisplayRectangle.Y;
nextControlLocation.X += c.Width + c.Margin.Right + parent.Padding.Horizontal;
}
return false;
}
}
}
One thing that took a while is that changing the location / size of one ToolStrip item will cause the layout to re-fire, with the controls reordered. So I take a copy of the controls before the layout loop.
And you cant use AddRange(...) to add items to the Custom Panel for some reason - need to Add(...) them one at a time.
hope that helps (it's based on MSDN LayoutEngine Example, fixed for ToolStripPanels)
Wyzfen
System.Windows.Forms.FlowLayoutPanel can do the job.
Just put the ToolStrip controls in it with correct order.
I think in your case you can get away with just setting the LayoutStyle on your ToolStrip to ToolStripLayoutStyle.HorizontalStackWithOverflow rather than need your own custom LayoutEngine.
I asked a different question on a similar topic on how to handle layout with dynamic items to have better control of the overflow.