How to catch QComboBox popup close event - qt

A am using QComboBox derived class to show my items. My combo box is read only. But how can I catch the event when popup view of combo box closes?.For example, when user clicks a mouse button somewhere out of my combo box?
Thank you very much in advance.

What for do you want this event? If the QComboBox closes without selection nothing changed. The signals given will only be activated when a selection has been made.
If you insist on reading a "close-event", you could subclass focusOutEvent(QFocusEvent*) or use an event handler for the focus out event and emit a custom signal. Eventually you want to have a boolean flag set on hadEditFocus() before, so you can see if the dropdown would be opened.
Edit:
Eventually it would be easier to subclass and reimplement showPopup() and hidePopup() as:
void MyClass::showPopup()
{
QComboBox::showPopup();
emit signalPopupShown();
}
void MyClass::hidePopup()
{
QComboBox::hidePopup();
emit signalPopupHidden();
}
but I am not sure if hidePopup() gets called on focus-loose.

Related

How to find subsequent (all) SLOT from a subclass

I need to block specific buttons on an MMI.
I implemented a button blocking function in a subclass of QPushButton.
For this, I used the clicked() signal and blocked the button with blockSignals(true).
This means that with each button clicked on my MMI, 2 SLOTS are always called.
But when calling the blocking of a specific button, I get the first SLOT (clicked()) of my subclass, in which I block the button, then I then arrive in the original SLOT linked to this button, which is still called despite the blocking (the first time only).
How can I in my QPushButton subclass know the subsequent SLOTs linked to this button and avoid them (delete them)?
void QbtnStandardButton::slotButtonClicked(void)
{
if (modeProtection)
{
// Special mode to protect/unprotect the button
if (isProtected())
{
// Reset the protection
this->blockSignals(false);
}
else
{
// Set the protection: button will be unclickable
this->blockSignals(true);
}
modeProtection = false;
}
if (isProtected())
{
QMessageBox *pMsgBox = new QMessageBox(QMessageBox::Information,
"Protection",
"This button is protected!",
QMessageBox::Ok);
pMsgBox->exec();
pMsgBox->deleteLater();
// Here: remove subsequent SLOT of this button ?
}
}
I think it's very difficult if not impossible to find SLOTS linked to a button.
I worked around the problem by using an eventFilter() instead of a SIGNAL() in my base class.
In this case, I can filter the "clicked()" event before it is reissued.

How to hide a QWidget when mouse clicked on out side that widget

I want hide a QWidget when mouse clicks out of that widget just like it have a popup flag:
auto widget = new QWidget(this);
widget->setWindowFlag(Qt::Popup); // this widget will hide, when mouse click out of that widget.
For some reason, I can't set these flags and must implement some thing myself which behaves like this.
Or can I get a mouse event out of that widget?
Solution:
As I said, I can't use Qt flags and have to implement the similar behavior myself.My solution is installEventFilter to QApplication, in the override method eventFilter,I filter the QMouseEvent and send a signal.
Yes, you can get a mouse event out of the widget.
Make a custom widget and reimplement mousePressEvent, which will catch the last click (the ouside-the-widget click that hides the "popup"). But be careful to add the call to QWidget::mousePressEvent(event) in the end, otherwise the last click will be lost and your widget will remain onscreen.
CustomWidget::CutomWidget(QWidget *parent) : QWidget(parent)
{
setWindowFlags(Qt::Popup);
}
void CustomWidget::mousePressEvent(QMouseEvent *event)
{
if (!this->underMouse()) {
//if the click is not on the widget, i.e. if it's the click that hides it,
// you caught it, do what you want to do here.
}
QWidget::mousePressEvent(event);
}
Hope it helps.

Triggering an action based on its custom shortcut

Suppose I have some action to happen. For that I can create a QAction object and connect its triggered() signal to the slot that executes the desired function. Also, I can have a shortcut associated with the action; by changing the shortcut I'll be able to execute the same action with that shortcut.
My problem now is that the "shortcut" I wanna set to the action, contains also a mouse button press (and mouse events cannot be assigned to action shortcuts); say I want Shift+Left mouse button. Maybe this sounds a little bit harsh but bear with me.
What do I need? Well, I have a button, and an action (say "execute a script"). I want the script to execute when Shift+Left click is clicked, and I want this "shortcut" to be customized, i.e. the user should be able to change to shortcut to, say Ctrl+Left click (from some GUI element, e.g. button text), and now Ctrl+Left click should execute the script.
How can I achieve this?
Note: I as a user would expect an action triggered by a mouse button to be position dependent. If so, the following gets a bit simpler.
Qt doesn't have an option to specify such a shortcut.
You can roll your own by reacting to mouse events:
Maybe you have an event handler mousePressEvent(),
or a generic eventFilter(QObject *obj, QEvent *evt),
or utilize QApplication::notify
Whichever, at some place you need to catch a QMouseEvent *mouseEvt.
Choose the widget (or qApp) that is as outmost as needed.
There, compare mouseEvt->button() and mouseEvt->modifiers() to your list of actions and trigger the selected action. When the user chooses another trigger method, adjust your list of actions.
Let's put this to practice:
class MainWindow : public QWidget {
Q_OBJECT
public:
QMap<QPair<Qt::MouseButton, Qt::KeyboardModifiers>, QAction*> mapMouseShortcuts;
QAction *pLaunchScript;
MainWindow() : QWidget() {
mapMouseShortcuts.insert(qMakePair(Qt::LeftButton, Qt::ControlModifier), pLaunchScript);
}
void mousePressEvent(QMouseEvent *me) {
QAction *action = mapMouseShortcuts.value(qMakePair(me->button(), me->modifiers()), Q_NULLPTR);
if(action != Q_NULLPTR) {
action->trigger();
me->accept(); // optional
}
// optional:
if(!me->isAccepted()) {
QWidget::mousePressEvent(me);
}
}
};

Switch widget: onClick event works but how to listen when you slide the switch?

I have a switch widget as per XML below and have onToggleClicked function which is working fine when you click on switch. But What I noticed is that you can actually slide the switch from one position to another and onClick event is not triggered in his case. How to disable sliding of the switch or how to monitor state change of the switch??
thanks a lot.
There is only one way I have found to listen to the sliding event of the switch, using an OnCheckedChangeListener from the class CompoundButton. Like this, for example:
exampleSwitch = (Switch) findViewById(R.id.exampleSwitchID);
exampleSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//your actions when the button has changed the status
//the boolean isChecked tells you if the button is activated or not
}
};);
The only problem this might have is, if you change the state of the button programatically (exampleSwitch.setChecked(boolean)) it will fire the listener. If you don't want that to happen, before setting the state of the button set the listener to null. For example:
exampleSwitch.setOnCheckedChangeListener(null);
exampleSwitch.setChecked(boolean);
exampleSwitch.setOnCheckedChangeListener(listener);
I hope this help.

How to get Click Event of QLineEdit in Qt?

How to get Click Event of QLineEdit in Qt ?
I am not able to see any SLOT related to click in QLineEdit ?
I don't think subclassing a QLineEdit is the right choice. Why subclass if you don't need to? You could instead use event filters. Check out QObject::eventFilter.
Example:
MyClass::MyClass() :
edit(new QLineEdit(this))
{
edit->installEventFilter(this);
}
bool MyClass::eventFilter(QObject* object, QEvent* event)
{
if(object == edit && event->type() == QEvent::FocusIn) {
// bring up your custom edit
return false; // lets the event continue to the edit
}
return false;
}
You need to reimplement focusInEvent in a new class extending QLineEdit. The following links are going to help you.
http://doc.qt.io/qt-5/qwidget.html#focusInEvent
QLineEdit - focus event
How to know if a QLineEdit got focus?
QLineEdit Focus Event
Although there is no "clicked" or "entered" event. You can use the
void cursorPositionChanged(int old, int new)
Signal. It is emitted when the user clicks the lineedit (if it is enabled) and also on a few other occasions so you have to verify which of the events actually happened but I think this is still easier than subclassing or using the event listener for some applications.
I dono if this will help,
i had to call a function once a text is entered. This is how i did it.
connect(ui->passwordSetLineEdit,SIGNAL(textEdited(QString)),this,SLOT(onTextEdit(QString)));
when a text is entered textEdited signal will be emited, thus my onTextEdit function will be called.
There is no signals like clicked() for QLineEdit, but you can subclass it and emit such signal in your custom implementation of mouseReleaseEvent.
I used this solution many times
def clickable(widget): # make this function global
class Filter(QObject):
clicked = pyqtSignal()
def eventFilter(self, obj, event):
if obj == widget and event.type() == QEvent.MouseButtonRelease and obj.rect().contains(event.pos()):
self.clicked.emit()
return True
else:
return False
filter = Filter(widget)
widget.installEventFilter(filter)
return filter.clicked
clickable(self.lineedit).connect(self.test) #use this in class
def test(self):
print("lineedit pressed")
pass
Just use the Pushbutton clicked event. Change the backcolor of the Pushbutton into Transparent then remove the text of it. Lay it in front of the LineEdit then use the setfocus property of the LineEdit when the push button was clicked. That's the easiest way to get the clicked event and use it in LineEdit.. 😉

Resources