Disable keyboard shortcut (delphi) - delphi

I created a form in Delphi.
Say I have a Form with a speedbutton with label "&Add" (underline A, as a keyboard shortcut), and a dbgrid (read-only state) (or other control like TButton).
Then I changed the focus to Dbgrid (dbgrid got a focus) (or to TButton).
Every time I press the a key on the dbgrid, the onClick method on the speedbutton triggers.
Sometime I need to disable it for a while for a reason, and then i enable it again.
How to disable the speedbutton shortcut?
And then how to enable it again?

The form is pressing the button when you press A because the button has expressed interest in that key, and nothing else on your form is accepting keystrokes. If you had an edit box on your form, and it had the input focus, then the button would not be triggered.
You can make a control indicate that it wants to receive keystrokes when it has the focus, but that generally happens when writing a custom control, where you have some idea of what the new control class should do when it receives keyboard input.
If you don't want the button to be triggered, you can disable it. Another option is to alter the OnClick event handler to check other conditions (such as whether the grid has focus) before performing the usual click-handling code.

You could disable the shortcut by changing the speed button's label from &Add to Add. Change it back when you need to enable the shortcut again.
Please note that specifying an accelerator character like that enables two shortcuts, one is just the key prefaced with the & and the other the same key with Alt. So, in your case they would be A and Alt+A. In the same way, eliminating the accelerator disables both shortcuts. So, keep in mind that with this method of disabling the shortcut you would be unable to trigger the button neither with A nor with Alt+A.

Related

how to respond to a key press when focused on a radiogroup in delphi

In delphi:
How can you respond to a key press when the current focus is on a radiogroup which does not have an onkeypress event. I was hoping to use the forms onkeypress event but it doesnt see to fire.
You can make this possible by setting the form's KeyPreview property to True.
However, I'm not sure you are actually doing things right, since this is a fairly uncommon problem.
You didn't write what keyboard shortcut you want to respond to. But please remember that
Letters are used to navigate the GUI. For instance, pressing A might select the &All radio button or click the &Add push button. Similarly, Alt+A does the same if the current control allows character input, allows you to open the &Add-ons menu item, etc.
If you want to add a proper shortcut like Ctrl+O, it is much better to use a TActionList with an action having this shortcut. This action can be mapped to menu items, buttons, etc., or simply exist in the background not being attached to any visual control. In very simple applications, you might want to use a stand-alone menu item with such a shortcut instead.

TToolbar Button with dropdown menu greyed out

I'm having issues getting a TToolbar Button to appear "enable"
The button has an Action assigned to it - which is fire by the OnClick event
It is also setup with a Drop Down Menu, which has 2 options on it, both of which are enabled, and both of which fire off when clicked.
Despite all this the TToolbar Button steadfastly remains greyed out, but accepts the clicks.
Any suggestions?
You're doing things wrong. :-)
When using actions, you don't use the button's OnClick event - you put the code in the action's OnExecute event instead (because that's what's executing - the action - and not the button). When an action is assigned to the control, the control cannot be enabled until there's a handler for the TAction.OnExecute.
The reason for using actions is so you can put the code in a single place (events related to the action), and then every single control attached to that action uses that common code to perform the same functionality. Editing the code in that single location means all controls attached to that action see the same changes.
If there's nothing attached to the TAction.OnExecute event, the control has nothing to do if it was selected (clicked), and so there's no reason to enable it in the first place.
In case someone else comes across this, I just had this problem (using Delphi 10.2 Tokyo).
For some reason, the "EnableDropdown" property on the TToolButton caused the button to to be greyed out when set to true. Setting this property to false seems to have resolved the problem for me (the dropdown menu remains functional anyway).

combobox steal keyboard from main window in pyqt

I'm writing a small pyqt program. I want the main window to to react to arrow movement. I added an event to my MainGui class, keyPressEvent, that handle this. The event work fine as long as I don't press certain buttons such as Key_Up or Key_Down are directed to my (currently only) QComboBox and not to my mainGui. I tried to give the focus to mainGui after each paintEvent but then I need to double click on buttons/comboBox.
Then I tried to use the MousePressEvent to check if a certain element is under the mouse. This work fine with the comboBox, but not with the button.
So, how can I direct key events to the mainGui or give the focus to QButtons?
I used eventFilter to identify when the mouse enter the QPushButton and give it focus:
def eventFilter(self,source,event):
if event.type() == QtCore.QEvent.HoverMove:
if self.execButton.underMouse():
self.execButton.setFocus()
self.keepFocus=False
else :
self.keepFocus=True
keepFocus is a flag I initialized in the __init__ function of the class. I added this part at the paintEvent function
if self.keepFocus:
self.setFocus()
else:
self.keepFocus = True
Now, I keep the focus at the MainGui and I only give it to the button when the mouse hove over it. If I do another action (like pressing a mouse button or a keyboard key) the focus is given back to the MainGui. This will create some buggy filling (For example, I need to press twice a keyboard key before the first response) but this is workable.

DateTimePicker tab between fields

Is there anyway to allow the user to tab between the fields in the TDateTimePicker.
Having to use arrow keys or the mouse to position is very slow.
No, there is no way.
Interception of the TAB and sending a right arrow key -> instead is easy, but then you have to decide when to let (SHIFT-)TAB trough, which should be done when standing on the first or last field in order to preserve normal user experience.
Now, all the selection changes from cursor and mouse events are internally handled within the Windows DTM control, and the Windows API does not support retrieving the separate fields. All you can acquire is the entire text of this very special edit control.
In theory you could intercept and save áll keyboard and mouse input, and calculate whether the first or last field is selected, but it will be a daunting and an error-prone task, and you should not want to.
Thus no. You just have to get yourself familiarized with it.

TStringGrid dirty hack - Restricting the selection to one single row

I have a heavily modified control based on TStringGrid. I want to allow the user to make selections in this grid but restrict the selection one single row (the current row).
Implementation:
When the user presses the left mouse button I am using a dirty hack: On OnMouseDown event I capture the mouse cursor and keep it on the current row. The user can move the mouse device up and down on its pad but the cursor will not go up or down. It will stay on the current row. When the user releases the button (OnMouseUp event), I release the capture.
However, this hack is as I said very dirty. There are several problems. For example, if the user presses the left mouse button (LMB) and then without releasing that button it presses the right button, the associated pop-up menu will pop but the mouse capture will never be released. So, the mouse will be locked in a screen region until the user will has the brilliant idea to click the LMB one more time to unlock the mouse. This may be a bug in D7. There is a separate post about it here: TStringGrid - OnMouseUp is not called!
There is a elegant way to do this?
Edit:
OnSelectCell is not working. OnSelectCell event is called only once when you click the cell. If you keep the button pressed and move the mouse to expand the selection, OnSelectCell will not be called again.
Indeed MoveCurrent appears only in TCustomGrid.MouseDown.
Use the OnSelectCell event and set the CanSelect var parameter depending on whether the ARow parameter is what you want.
A nice solution
Check the options property on TStringGrid
There is an Option called 'goRangeSelect'
Set this to false using the object inspector
Or programatically this can be done by
StringGrid1.Options - [goRangeSelect];
This answer is not elegant at all, but it works.
My solution is NOT to use the PopupMenu property of the StringGrid. Instead I implemented my own PopUpMenu property. Works almost perfect. There is on small problem, the bottom of the pop-up menu appears next to the cursor and not its top.

Resources