Ignore mouse and keyboard events in Qt - events

In Qt, how can I ignore all mouse and keyboard events and later stop ignoring them? That is: click a button, ignore all events in children; click again, not ignore. Is that clear?
I have the following lines, but maybe I'm doing something wrong:
setAttribute(Qt::WA_TransparentForMouseEvents);
setFocusPolicy(Qt::NoFocus);

Dont use setFocusPolicy(Qt::NoFocus); and it will propagate events to the parent. Use only setAttribute(Qt::WA_TransparentForMouseEvents);

You can use Events' filters on your mouse and keyboard events to filter some keypress or mouseclick when you need so :
yourWidget->installEventFilter(this);
...
bool YourFrm::eventFilter(QObject* pObject, QEvent* pEvent)
{
if (pEvent->type() == QEvent::KeyPress)
{
QKeyEvent* pKeyEvent = static_cast<QKeyEvent*>(pEvent);
int PressedKey = pKeyEvent->key();
if(PressedKey == Qt::Key_Return)
{
// Filter Return key....
return true;
}
// standard event processing
return QObject::eventFilter(pObject, pEvent);
}
else if (pEvent->type() == QEvent::MouseButtonPress)
{
QMouseEvent* pMouseEvent = static_cast<QMouseEvent*>(pEvent);
... // etc...
}
else
{
// standard event processing
return QObject::eventFilter(pObject, pEvent);
}
}
More informations on this : http://qt.nokia.com/doc/4.6/eventsandfilters.html
Hope it helps !

You could use:
QWidget::setEnabled(false)
it disable mouse and keyboard events for a widget.

Do you mean for a QGraphicsItem ?
If yes, you can call
void QGraphicsItem::setEnabled ( bool enabled )
And to activate the event later, as the item doesn't receive events any more, you have to pass by the Scene, because you can't receive directly event on the item.
If your problem is not using GraphicsView Frameworks, but other part of qt, it's almost the same process :
You can call :
QWidget::setEnabled(false) //like Massimo said
In order to reactive the widget, just detect press event inside an object in your application to be able to call `setEnable(true) on your widget !
Hope it helps !
`

Related

Xamarin, how can I gain a completed state from a command?

I have a ListView and am using the SelectedItem to call a command and show a modal view.
However, I have an issue where the user can tap multiple times on the listview row and multiple modal views are shown before the view has loaded. Granted this only happens on slower devices.
This is is caused because the command doesn't have any call back.
I wouldn't normally paste code here, but in this case I thought it was more descriptive to provide a screen shot.
I've looked into the AsyncCommands but these seem to be used more to handle errors.
I'm currently thinking about a subscribe approach which is triggered when the modal is exited, however I think there must be another way I haven't thought of.
Can you try using a Boolean as IsSelected & make IsSelected true when user clicks an item from list & change your condition in setter as below. When your operations are done reset the flag.
This was, there wont not be any duplication of modals. This is what I understood from your question, if there's something else, please let me know.
if( _locationAssetSelected || !IsSelected )
{
IsSelected = true;
_locationAssetSelected = value;
..... //your code
_locationAssetSelected = null;
IsSelected = false;
}
You could move the logic to the command to make sure it doesn't execute multiple times. This is a snippet on the sample/template Forms app which uses this method as a command. Lock seems unnecessary.
async void OnItemSelected(Item item)
{
//lock (selectLock)
//{
if (item == null || selectionOn)
return;
selectionOn = true;
//}
System.Diagnostics.Debug.WriteLine($"{item.Text} selected");
// This will push the ItemDetailPage onto the navigation stack
await Shell.Current.GoToAsync($"{nameof(ItemDetailPage)}?{nameof(ItemDetailViewModel.ItemId)}={item.Id}");
selectionOn = false;
}

Unity onClick.addlistener not working

I load a Canvas prefab at runtime when an event occurs. The canvas simply has a Panel inside it, which in turn has 2 buttons. I'm trying to add OnClick events to both these buttons in the script, but it only works for the first button somehow!
I have the following two lines of code one after the other:
GameObject.Find("RestartButton").GetComponent<Button>().onClick.AddListener(() => RestartClicked());
GameObject.Find("ViewButton").GetComponent<Button>().onClick.AddListener(() => ViewClicked());
The callback only works for the RestartButton, and not for the ViewButton.
It may well be a very small thing, but I searched Google and Bing extensively and remain clueless, so any help would be appreciated.
Thanks!
Edit:
The script instantiates the prefab and tries to reference the two buttons in the prefab through GameObject.Find(), given that once Instantiate is called the Canvas should be active in the heirarchy.
I also opened up the part of the code that attaches buttons to the listener for debugging. I dont think it attaches the listener at all.
void Start () {
SetupScene();
var prefab = Resources.Load("RestartOrViewPrefab");
if (prefab == null)
{
Debug.LogAssertion("Prefab missing!");
return;
}
restartCanvas = (GameObject)Instantiate(prefab);
Button btn = GameObject.Find("ViewButton").GetComponent<Button>();
btn.onClick.RemoveAllListeners();
btn.onClick.AddListener(() => ViewToggle());
Button btn2 = GameObject.Find("RestartButton").GetComponent<Button>();
btn2.onClick.AddListener(() => RestartClicked());
}
private void RestartClicked()
{
Debug.Log("RESTARTING");
SetupScene();
}
private void ViewToggle()
{
Debug.Log("TOGGLE");
if (freshStart)
{
//Something here
freshStart = false;
}
else
{
//Something else here
freshStart = true;
}
}
So I took two days to solve my problem. Apparently, doing a GameObject.Find() for a GameObject within a prefab that you just instantiated doesn't work. We always need to use the GameObject that the Instantiate() method returns to find any component within the prefab.
The code I used to make my scene work may not be the best solution if your prefab is very big/complex (say you have 15 buttons and need to do something with one), but it sure does work. :)
I replaced the following lines of code:
Button btn = GameObject.Find("ViewButton").GetComponent<Button>();
btn.onClick.RemoveAllListeners();
btn.onClick.AddListener(() => ViewToggle());
Button btn2 = GameObject.Find("RestartButton").GetComponent<Button>();
btn2.onClick.AddListener(() => RestartClicked());
With the following lines of code:
Button[] buttons = restartCanvas.GetComponentsInChildren<Button>();
foreach(Button but in buttons)
{
if(but.gameObject.name == "RestartButton")
but.onClick.AddListener(() => RestartClicked());
else if(but.gameObject.name == "ViewButton")
but.onClick.AddListener(() => ViewToggle());
}
So I just reused the restartCanvas that I got a reference to.
restartCanvas = (GameObject)Instantiate(prefab);
Hope this helps someone. :)
I answered this on another post, but I'll answer it here for people that still need this info.
The GameObject your instantiated button is a child of must have a CanvasRenderer component on it.
I'm not sure why this works, but it does.
Once the parent of the button GameObject has the CanvasRenderer on it, you can call myButton.onClick.AddListener(() => MyMethod(MyArgs)); as you normally would.
Ok make sure you are not getting any null reference error, and check tht spelling of you buttons , output some debug logs in your second function to see if its even reaching there

How to intercept MouseEvent.MOUSE_CLICKED on TableView on JavaFX8

I am creating a custom CheckBoxTableView where the selected items are displayed with a CheckBox. If the user attempts to sort the table once items are selected, it appears to mess up. I would like to prompt the user to see if they would like to continue. If so, I would like to clear the selection, if not, simply consume the event so the sorting doesn't happen.
Unfortunately - my EventFilter seems to fire after the sort was completed.
On the TableView constructor, I placed the following code:
addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
if(event.getTarget() instanceof TableColumnHeader) {
Alert a = new Alert(Alert.AlertType.CONFIRMATION);
a.setContextText("you sure?");
Optional<ButtonType> bt = a.showAndWait();
if(bt.isPresent() && bt.get() == ButtonType.OK){
//Clear selection
getSelectionModel().clearSelection();
}else {
event.consume();
}
}
});
But by the time my EventFilter fires, the table has been sorted.
Any thoughts?
Use MouseEvent.MOUSE_PRESSED
MouseEvent.MOUSE_CLICKED is fired after MouseEvent.MOUSE_RELEASED that's too late to intercept listeners and listeners :)

jquery terminal custom tab completion

Is it possible to take control of the entire tab-completion feature in JQuery.Terminal? I want to manage the autocompletion that's displayed.
For instance, I want to support templates/regex so that I can do things like "visualize campaign CAMPAIGN_NAME where config = SOMETHING". I could write my own parser and handler for all this, but I'm not sure how/where to plug it in?
In initialization settings, you need to make sure that the completion attribute is not set (default is false).
Then, you need to intercept the keydown function and handle the key you're interested in (tab in my case).
In there you can provide your own handler for auto-completion logic:
$('#terminal').terminal(function (command, term)
{
// Command handlers
},
{
keydown: function(event, term) {
if (event.keyCode == 9) //Tab
{
// Call handler to handle your auto-completion logic
// Sample to print stuff to the console and update the command
term.echo("autocompletion commands...");
term.set_command(term.get_command() + " completion text");
// Tells the terminal to not handle the tab key
return false;
}
}
});
});

map keyboard keys with mootools

I am looking to make the enter key behave exactly like the tab key on a form.
I am stuck on the fireEvent section.
var inputs = $$('input, textarea');
$each(inputs,function(el,i) {
el.addEvent('keypress',function(e) {
if(e.key == 'enter') {
e.stop();
el.fireEvent('keypress','tab');
}
});
});
How do I fire a keypress event with a specified key? Any help would be greatly appreciated.
this will work but it relies on dom order and not tabindex
var inputs = $$('input,textarea');
inputs.each(function(el,i){
el.addEvent('keypress',function(e) {
if(e.key == 'enter'){
e.stop();
var next = inputs[i+1];
if (next){
next.focus();
}
else {
// inputs[0].focus(); or form.submit() etc.
}
}
});
});
additionally, textarea enter capture? why, it's multiline... anyway, to do it at keyboard level, look at Syn. https://github.com/bitovi/syn
the above will fail with hidden elements (you can filter) and disabled elements etc. you get the idea, though - focus(). not sure what it will do on input[type=radio|checkbox|range] etc.
p.s. your code won't work because .fireEvent() will only call the bound event handler, not actually create the event for you.
Take a look at the class keyboard (MooTools More).
It can fire individual events for keys and provides methodology to disable and enable the listeners assigned to a Keyboard instance.
The manual has some examples how to work with this class, here's just a simple example how I implemented it in a similar situation:
var myKeyEv1 = new Keyboard({
defaultEventType: 'keydown'
});
myKeyEv1.addEvents({
'shift+h': myApp.help() // <- calls a function opening a help screen
});
Regarding the enter key in your example, you have to return false somewhere to prevent the enter-event from firing. Check out this SO post for more details.

Resources