I have two processes which exange messages each other.
Process A is a normal (i.e non-qt) program which sends messages to process B.
Process B is a QT GUI application showing received messages into a text box.
I created a customized widget (called ShowMessages) which inherits from QPlainTextEdit and reads messages from a pipe when a timer expires, and appends them in the text box.
Code is not really designed like this (which would be pretty bad design I think), but it's just to make things simple here.
For reasons I won't tell, process A cannot be shut down while I'm creating the form using qt-designer.
Problem is that while I'm using qt designer (thus selecting the ShowMessages widget and putting it within the window) the widget begins to show messages, even if I'm in the designer. This feature is cool but the problem is that when I save the form, already present messages are saved in .ui file, which results in turn in bad behaviour when I start process B (because process starts showing messages I received during the creation phase).
I could clean the text box just after process B starts, but I think that avoiding messages to be present in the .ui file is much better. What I want is to be able to write code like this for the widget:
if <I'm not in the designer>
timer = QtCore.QTimer(self)
QtCore.QObject.connect(timer, QtCore.SIGNAL("timeout()"), self, QtCore.SLOT("on_timer()"));
timer.start(2000)
Is there an qt function to know if I'm in the designer? Do you think that distinguishing between designer and runtime code is "bad"?
(Sorry for mistakes, but English is not my primary language)
Maybe your widget should have a flag for whether it's "active" and default it to False so while you're in the designer, it doesn't do anything at all. In code you would set it to active when you want to see the messages. Then you also have the ability to turn it off in other scenarios as well.
But I have to say, it sounds like you're putting "controller" code into a "view" widget which can and probably will spell trouble for you down the road (including the current Qt designer problem you're having now).
Consider reading up on the MVC (model-view-controller) design pattern, if you haven't already.
Update:
To be fair, your question did ask how to detect whether you're in designer :)
http://doc.trolltech.com/4.3/designer-creating-custom-widgets.html#creating-well-behaved-widgets
To give custom widgets special
behavior in Qt Designer, provide an
implementation of the initialize()
function to configure the widget
construction process for Qt Designer
specific behavior. This function will
be called for the first time before
any calls to createWidget() and could
perhaps set an internal flag that can
be tested later when Qt Designer calls
the plugin's createWidget() function.
According to the doc, you basically could set your "inDesignerFlag" to true in the initialize() function of your widget. Then detect that flag where required in your widget's code.
Related
I am trying to keep the business process flow display state as collapsed.
I am currently making it collapsed at addOnStageChange
Xrm.Page.ui.process.setDisplayState('collapsed');
It works fine on Stage Change for me. But if I click on the same stage twice which means stage is not changing then the BPF gets expanded. I am assuming if it is the default behavior.
How can I prevent it from expanding permanently?
If you are using Unified Interface it will be collapsed by defualt.
But if you are using legacy web client.
Add onload event on your From (for ex.Opportunity entity) and add below lines of code.
function collapseOpporBusinessProcess(){setTimeout(collapseOpporBusinessProcessDelay,300)}
function collapseOpporBusinessProcessDelay(){Xrm.Page.ui.process!=null&&Xrm.Page.ui.process.setDisplayState(“collapsed”)}
BPF cannot be collapsed always in classic UI, but possible in UCI like popout behavior or flyout without expanding. It needs some unsupported DOM manipulation in classic UI to nullify the click event of stage chevron or simply user training not to click it at all. Or better create a similar UI using webresource if you want.
It fails the original purpose, and re-purposing the BPF raise these kind of questions. If you have built the necessary business logic already in some other means - then custom UI is better choice rather than bending the BPF.
BPF is for guided process advancement, we can add attributes/entities as steps to move forward and enforce the field value requirements for reaching next level. I know some clients use them as tabs, some use them as just chevron tracker, so they don't want to waste the real estate under the BPF as they don't need any fields under the stages.
I'm trying to intercept the change events triggered (any field) when this property window is changed in a VS Extension project (vsix). This extension will target VS versions upto 2019 (the latest one).
I've used dte.Events.TextEditorEvents.LineChanged but it captures the event intermittently.
Is there a specific event that I can look at for this purpose?
Initially I mistakenly thought IVsRunningDocTableEvents.OnAfterAttributeChange could be used. But after reviewing the designer code base (one of the few I've seen written in VB.NET), I found that this particular designer sets the windowframe's dirty by explicitly invoking IVsWindowFrame.SetProperty with VSFPROPID_OverrideDirtyState, which per the comments in the vsshell80.idl file:
VSFPROPID_OverrideDirtyState = -4014, // BOOL/EMPTY -- tri-state value to control dirty star (*) in window caption
// VT_EMPTY: default handling of dirty star
// VARIANT_TRUE: override default handling to SHOW dirty star
// VARIANT_FALSE: override default handling to show NO dirty star
indicates this designer doesn't leverage the default mechanism driven by the RDT. :-(
The only notification I could find that you could possibly intercept would be an IPropertyNotifyChange on the individual properties themselves, which does fire, as soon as you change a given setting and move focus to another control.
This may not be what you're looking for, but if you can explain why you need such a notification, I may be able to come up with something better than periodically polling the designers VSFPROPID_OverrideDirtyState property (which is the only other thing that immediately comes to mind).
Thanks,
Ed....
I'm working on a custom cross platform UI library that needs a synchronous "ShowPopup" method that shows a popup, runs an event loop until it's finished and automatically cancels when clicking outside the popup or pressing escape. Keyboard, mouse and scroll wheel events need to be dispatched to the popup but other events (paint, draw, timers etc...) need to be dispatched to their regular targets while the loop runs.
Edit: for clarification, by popup, I mean this kind of menu style popup window, not an alert/dialog etc...
On Windows I've implemented this fairly simply by calling GetMessage/DispatchMessage and filtering and dispatching messages as appropriate. Works fine.
I've much less experience with Cocoa/OS X however and finding the whole event loop/dispatch paradigm a bit confusing. I've seen the following article which explains how to implement a mouse tracking loop which is very similar to what I need:
http://stpeterandpaul.ca/tiger/documentation/Cocoa/Conceptual/EventOverview/HandlingMouseEvents/chapter_5_section_4.html
but... there's some things about this that concern me.
The linked article states: "the application’s main thread is unable to process any other requests during an event-tracking loop and timers might not fire". Might not? Why not, when not, how to make sure they do?
The docs for nextEventMatchingMask:untilDate:inMode:dequeue: states "events that do not match one of the specified event types are left in the queue.". That seems a little odd. Does this mean that if an event loop only asks for mouse events then any pressed keys will be processed once the loop finishes? That'd be weird.
Is it possible to peek at a message in the event queue without removing it. eg: the Windows version of my library uses this to close the popup when it's clicked outside, but leaves the click event in the queue so that clicking outside the popup on a another button doesn't require a second click.
I've read and re-read about run loop modes but still don't really get it. A good explanation of what these are for would be great.
Are there any other good examples of implementing an event loop for a popup. Even better would be pseudo-code for what the built in NSApplication run loop does.
Another way of putting all this... what's the Cocoa equivalent of Windows' PeekMessage(..., PM_REMOVE), PeekMessage(..., PM_NOREMOVE) and DispatchMessage().
Any help greatly appreciated.
What exactly is a "popup" as you're using the term? That term means different things in different GUI APIs. Is it just a modal dialog window?
Update for edits to question:
It seems you just want to implement a custom menu. Apple provides a sample project, CustomMenus, which illustrates that technique. It's a companion to one of the WWDC 2010 session videos, Session 145, "Key Event Handling in Cocoa Applications".
Depending on exactly what you need to achieve, you might want to use an NSAlert. Alternatively, you can use a custom window and just run it modally using the -runModalForWindow: method of NSApplication.
To meet your requirement of ending the modal session when the user clicks outside of the window, you could use a local event monitor. There's even an example of just such functionality in the (modern, current) Cocoa Event Handling Guide: Monitoring Events.
All of that said, here are (hopefully no longer relevant) answers to your specific questions:
The linked article states: "the application’s main thread is unable to process any other requests during an event-tracking loop and
timers might not fire". Might not? Why not, when not, how to make
sure they do?
Because timers are scheduled in a particular run loop mode or set of modes. See the answer to question 4, below. You would typically use the event-tracking mode when running an event-tracking loop, so timers which are not scheduled in that mode will not run.
You could use the default mode for your event-tracking loop, but it really isn't a good idea. It might cause unexpected re-entrancy.
Assuming your pop-up is similar to a modal window, you should probably use NSModalPanelRunLoopMode.
The docs for nextEventMatchingMask:untilDate:inMode:dequeue:
states "events that do not match one of the specified event types are
left in the queue.". That seems a little odd. Does this mean that if
an event loop only asks for mouse events then any pressed keys will be
processed once the loop finishes? That'd be weird.
Yes, that's what it means. It's up to you to prevent that weird outcome. If you were to read a version of the Cocoa Event Handling Guide from this decade, you'd find there's a section on how to deal with this. ;-P
Is it possible to peek at a message in the event queue without removing it. eg: the Windows version of my library uses this to close
the popup when it's clicked outside, but leaves the click event in the
queue so that clicking outside the popup on a another button doesn't
require a second click.
Yes. Did you notice the "dequeue:" parameter of nextEventMatchingMask:untilDate:inMode:dequeue:? If you pass NO for that, then the event is left in the queue.
I've read and re-read about run loop modes but still don't really get it. A good explanation of what these are for would be great.
It's hard to know what to tell you without knowing what you're confused about and how the Apple guide failed you.
Are you familiar with handling multiple asynchronous communication channels using a loop around select(), poll(), epoll(), or kevent()? It's kind of like that, but a bit more automated. Not only do you build a data structure which lists the input sources you want to monitor and what specific events on those input sources you're interested in, but each input source also has a callback associated with it. Running the run loop is like calling one of the above functions to wait for input but also, when input arrives, calling the callback associated with the source to handle that input. You can run a single turn of that loop, run it until a specific time, or even run it indefinitely.
With run loops, the input sources can be organized into sets. The sets are called "modes" and identified by name (i.e. a string). When you run a run loop, you specify which set of input sources it should monitor by specifying which mode it should run in. The other input sources are still known to the run loop, but just ignored temporarily.
The -nextEventMatchingMask:untilDate:inMode:dequeue: method is, more or less, running the thread's run loop internally. In addition to whatever input sources were already present in the run loop, it temporarily adds an input source to monitor events from the windowing system, including mouse and key events.
Are there any other good examples of implementing an event loop for a popup. Even better would be pseudo-code for what the built in
NSApplication run loop does.
There's old Apple sample code, which is actually their implementation of GLUT. It provides a subclass of NSApplication and overrides the -run method. When you strip away some stuff that's only relevant for application start-up or GLUT, it's pretty simple. It's just a loop around -nextEventMatchingMask:... and -sendEvent:.
New to GWT here...
I'm using the UIBinder approach to layout an app, somewhat in the style of the GWT Mail sample. The app starts with a DockLayoutPanel added to RootLayoutPanel within the onModuleLoad() method. The DockLayoutPanel has a static North and a static South, using a custom center widget defined like:
public class BigLayoutWidget extends ResizeComposite {
...
}
This custom widget is laid out using BigLayoutWidget.ui.xml, which in turn consists of a TabLayoutPanel (3 tabs), the first of which contains a SplitLayoutPanel divided into WEST (Shortcuts.ui.xml) and CENTER (Workpanel.ui.xml). Shortcuts, in turn, consists of a StackLayoutPanel with 3 stacks, each defined in its own ui.xml file.
I want click events within one of Shortcuts' individual stacks to change the contents of Workpanel, but so far I've only been able to manipulate widgets within the same class. Using the simplest case, I can't get a button click w/in Shortcuts to clear the contents of Workpanel or make WorkPanel non-visible.
A few questions...
Is ResizeComposite the right type of class to extend for this? I'm following the approach from the Mail example for TopPanel, MailList, etc, so maybe not?
How can I make these clicks manipulate the contents of panels in which they do NOT reside?
Are listeners no longer recommended for handling events? I thought I saw somewhere during compilation that ClickHandlers are used these days, and the click listener "subscription" approach is being deprecated (I'm mostly using #UiHandler annotations)
Is there an easy way to get a handle to specific elements in my app/page? (Applying the "ID" field in the UI.XML file generates a deprecation warning). I'm looking for something like a document.getElementById() that get me a handle to specific elements. If that exists, how do I set the handle/ID on the element, and how can I then call that element by name/id?
Note that I have the layout itself pretty well nailed; it's the interaction from one ui.xml modularized panel to the next that I can't quite get.
Thanks in advance.
If you don't have a use for resizing events than just use Composite
What you want is what the GWT devs called message bus (implemented as HandlerManager). You can get a nice explanation in the widely discussed (for example, on the GWT Google Group, just search for 'mvp') presentation by Ray Ryan from Google I/O 2009 which can be found here. Basically, you "broadcast" an event on that message bus and then a Widget listening for that event gets the message and does its stuff.
Yep, *Handlers are the current way of handling events - the usage is basically the same so migration shouldn't be a problem (docs). They changed it so that they could introduce custom fields in the future, without breaking existing code.
If you've set an id for any DOM element (for Widgets I use someWidget.getElement().setId(id), usually in combination with DOM.createUniqueId()) you can get it via GWT.get(String id). You'll get then a RootPanel which you'll have to cast to the right Widget class - as you can see it can get a little 'hackish' (what if you change the type of the Widget by that id? Exceptions, or worse), so I'd recommend sticking with MVP (see the first point) and communicating via the message bus. Remember however, that sometimes it's also good to aggregate - not everything has to be handled via the message bus :)
Bottom line is I'd recommend embracing MVP (and History) as soon as possible - it makes GWT development much easier and less messy :) (I know from experience, that with time the code starts to look like a nightmare, if you don't divide it into presentation, view, etc.)
If I have a setting that is accessible via a menu item or configuration window that can change at runtime, for example "bold text on/off"; what are some good ways of ensuring that all applicable components are aware the value of this setting?
You didn't provide specifics of an implementation language, so the asnwer will be somewhat generic.
Assuming your GUI is in a language which supports even model (e.g. Java), simply have an event handler for any component which should be affected by settings and which gets triggered on an event "setting changed". Then call such event from the setting config window. Don't forget to redraw when all components are done updating (ore redraw as each component is updated).
An additional point is to hopefully have generic sub-components used.
As an example, if you are using label text with a certain font which is configurable, then use a common "label with configurable font" class which ensures you never need to assign the above event listener to every label you create.
If there will be a lot of setting I have implemented a sqlite DB to hold the changes for smaller amount of changes key value pair in a file is good enough. Then implement a observer design pattern so when any changes are done a list of gui classes are called to do the change.