Tkinter Leave event firing only on program startup? - button

I'm trying to place a small label hinting the user the keyboard shortcut bound to it, which works fine.
The problem arises when I'm leaving the button. The label disappears, but not quite. If I try to click the button in the area the label "used" to be, it won't fire, indicating that's it's somehow still there. So I thought maybe buttons have a Leave event already built in that raises them to the top level. I decided to try and override that, and basically tell the button go (or better yet, just stay) below the key-hint label hit_button.bind("<Leave>", hit_button.lower(hit_button_keyhint), to no avail. What am I doing wrong?
fg=hit_button['fg'])
hit_button_keyhint.place(relx=0.5, rely=0.85, anchor='center')
hit_button.bind("<Leave>", hit_button.lower(hit_button_keyhint))

You need to pass a function to the binding, Here you execute a function. (hit_button.lower(hit_button_keyhint))
To do so, you should use a lambda.
You can get some clarifications here:
Tkinter binding a function with arguments to a widget
But this should work:
hit_button.bind("<Leave>",lambda event, k=hit_button_keyhint:hit_button.lower(k)

Related

How to intercept / modify excape key functionality in Qt

I am trying to fix a bug in a Qt app which I did not write. The window changes the background color of the entire window to red and puts up some buttons, dialog boxes, etc. When the escape key is pushed, the boxes and buttons go away, leaving an empty red screen. The Cancel button does the right thing in returning to the previous window. I think I need to somehow be notified of when the escape key is pushed, and then call the same function as the cancel pushbutton does. Hopefully, I can limit the scope of this special action to when the problem window is up. I am an experienced programmer but a complete Qt newbie. This app is purely C++. To my knowledge, it does not appear to use any QML. I am still searching through the Qt online documentation, but any suggestions / examples are appreciated.
This depends a lot on your specific Qt version and setup of your application. That said, I'll take a shot at helping. In the class where you're trying to intercept the escape key press, assuming it's inheriting QObject, simply override the virtual function eventFilter. Inside your overridden instance of eventFilter, check that the QEvent type is a QEvent::KeyPress, and then check whether the key of that KeyPress is the escape key, and handle as needed.
Be sure that you pass the event out of your function, else you'll see your overridden function eat all events. If you explicitly want the event to be "eaten", simply do not return it from your function. For specifics and examples, check out documentation of QObject::eventFilter().

No event getting generated on button click in MFC

I have a dialog based application. I have one static text control and a button on this, both of which I have made invisible in the beginning. I want to show both the controls on reaching a certain condition. When I click this button, again I want to make both the controls invisible.
However, I am able to show and hide the control and also captured the button click event like this:
ON_BN_CLICKED(IDC_MY_BUTTON, &MyDlg::OnBnClickedMyButton)
and defined OnBnClickedMyButton().
But when I press the button, it is not pressed and the event is also not generated.
Any suggestions?
First check if the IDC_MY_BUTTON exists and is valid.
Remember to add DECLARE_MESSAGE_MAP() at the header file.
Also check at the BEGIN_MESSAGE_MAP(MyClass,MyParentClass) if the class
and the parent class you write are right.
I hope this helps.
I think the IDC_MY_BUTTON maybe is invalid or other control has the same ID.
Well, finally I have come to know that though the button was visible but on clicking it was not taking control, hence I used BringWindowToTop() to draw it on top. Now it is being clicked and OnBnClickedMyButton() is also being called.
But now the issue is that after calling BringWindowToTop() the button is not shown. It is shown only when I take the mouse pointer on it. Not able to understand what is the issue.

PyQt5 - Signals&Slots - How to enable a button through content change of lineEdit?

since there isn't any useful How-To for beginners of PyQt5, I'm stuck with a little problem about signals & slots.
I do have a lineEdit which will get a directory path by a dialog (which works fine).
If one starts the program this lineEdit is empty by default and that's ok. A button, which shall generate a file list and show it in a list view, exists. It's functionality is implemented already and working fine. This button by default is disabled when the program is started for the first time.
What I want to do now is, enabling the button when something is entered at the lineEdit and disabling it when the content is removed.
I gave it a shot with this:
self.lineEdit_SelectedDirectory.editingFinished.connect(self.pushButton_CreateFileList.setEnabled)
but I get the error that it has not enough arguments, which might be clear because there aren't any provided in this code line.
Again, this was just a guess. How would one do this?
I would love something which takes the content into account like that, that it decides whether the content is empty or not and than sets the appropriate value to the button.
thx in advance for the help.
Christian
Looks like you want the textChanged signal, since that sends the current text:
self.lineEdit_SelectedDirectory.textChanged.connect(
lambda text: self.pushButton_CreateFileList.setEnabled(bool(text)))

Flex tree droplocation indicator stuck (edit 2/4/10, almost a totaly different question)

OK I've got a little more research on this done so I'm going to totally rephrase the question:
I have two trees, I want to be able to drag items from one tree to the other. In the receiving tree I have some logic that allows or denys the drop. I am using the native cursor feedback Like this :
DragManager.showFeedback(DragManager.COPY);
DragManager.showFeedback(DragManager.NONE);
When the logic determines NONE it properly rejects the item except the drop position indicator sticks like in the screenshot.
I know now that neither dragComplete, nor dragDrop are being fired in this situation, so I have no function to put code into that would clean that up. So how can I listen for this drag rejection?
ScreenShot shows app After drop
alt text http://img687.imageshack.us/img687/2245/treeindicatorstuck.png
Thanks
~Mike
PS with my other question: how-do-i-detect-that-drag-and-drop-operation-ended We have a way of getting an event to fire so we can clean up the tree control. I'm attaching an event listener to the stage so that as the mouse is moved (maybe I'll put it on a timer)it will constantly check if dragmanager.isdragging if it's not it will fire the tree.hideDropFeedBack. This still begs the question, what event is changing the isDragging Boolean and how do I listen for it?
You need to call tree.hideDropFeedback(); or event.target.hideDropFeedback(); to remove the drop indicators.

How can I tell a QTableWidget to end editing a cell?

I'm showing a popup menu to select some values in a QTableWidget. The lowest item is a "Modify list" entry, when I select it a new window should automatically appear and the QComboBox should vanish and the cell return to a Qt::DisplayRole state.
Now Qt has all those nice API-calls like QTableWidget.edit() and QTableWidget.editItem(), what I'm really looking for is a QTableWidget.endEditing(), preferably without specifying the index of the cell, though I could get that using this call:
table.currentIndex()
… but I don't know if I can guarantee that the current cell is the cell being edited at all times.
Is there an API to close those kind of editors?
QTableWidget inherits 19 public slots from QWidget. One of those is setDisabled(), which should disable input events for that widget and all of its children.
I would try:
table.setDisabled( true );
table.setDisabled( false );
Although you said it does not work for you, there is an alternative method:
If you don't like that (the table loses focus, I believe), you can try using EditTriggers. For example:
table.setEditTriggers( QAbstractItemView::NoEditTriggers );
table.setCurrentItem(None) is what worked for me. (Don’t forget to block signals if you use some cellChanged/itemChanged slot function.)
This is with PyQt. For C++ I think replace None with NULL.
You may be able to use QTableWidget.closePersistentEditor() to close the editor. However, QAbstractItemView.closeEditor() may be closer to what you want, especially since you seem to be comfortable with the QModelIndex-based API and are already using a custom editor widget.
In my case, none of the options worked properly. So, I figured: I need to send the key press event to the line edit itself. The following works with QTreeView but probably does work with any other view or widget that opens a line edit to edit cells.
QWidget* editingWidget = treeView->findChild<QLineEdit*>();
if(editingWidget)
{
QKeyEvent keyPressEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier);
QApplication::sendEvent(editingWidget, &keyPressEvent);
QApplication::processEvents(); // see note below
}
In my case, I wanted to start editing another field directly when having finished editing one item. That is why I put processEvents there, in most cases you can probably remove that line.
PS: yeah, it's C++, but should be easily adaptable to Python. I found this thread when I searched for the C++ solution, so maybe it helps anyone else, too.
I can't speak for list widgets. But, I got here trying to do something similar.
I was double-clicking a cell, and based on the column, bringing up a sub-form with a list, then when that was closed move to the next appropriate column based on the value selected.
My problem was I could get the value in the cell and "select" the next appropriate cell, but the original cell stayed selected in edit mode!
It finally dawned on me that my double-click was selecting the cell, ie. editing.
A single-click selects the cell but doesn't open an edit mode.
Side note: Never could get that sub-form to act truly modal, so I created a loop in the calling form: while the sub form was visible, with the only code being app.processEvents()

Resources