onmouseover and click event QLineEdit - qt

How can I define onmouseover and click event for a QLineEdit? I want to make 2 signals as onmouseover() and clicked() for QLineEdit

You can install an event filter on your QLineEdit.
Here's an example:
QLineEdit *line_edit = new QLineEdit(this);
ui->verticalLayout->addWidget(line_edit);
line_edit->installEventFilter(this);
And in your event filter function you can do something like this: (This is a function you override)
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::MouseButtonPress)
{
qDebug() << "CLICK";
}
if(event->type() == QEvent::MouseMove)
{
qDebug() << "MOUSE OVER";
}
return false;
}

I'm afraid, you'll have to inherit QLineEdit and override void mouseMoveEvent ( QMouseEvent * event ) and void mousePressEvent ( QMouseEvent * event ) (or void mouseReleaseEvent ( QMouseEvent * event ) if you wish). And don't forget to call setMouseTracking(true); to track mouse moves, when no mouse button is held.

Related

QT QLineEdit focusout

I have a QLineedit with mask and qvalidator (subclassed)
How can i prevent to move away the focus if the input isn't match the mask or validator ?
Because neither mask nor qvalidator don't prevent to move away focus from QLineEdit.
And editingfinished isn't work because :
void QLineEdit::editingFinished()
This signal is emitted when the Return or Enter key is pressed or the line edit loses focus. Note that if there is a validator() or inputMask() set on the line edit and enter/return is pressed, the editingFinished() signal will only be emitted if the input follows the inputMask() and the validator() returns QValidator::Acceptable."
void MainWindow:n_lineEdit_editingFinished()
{
if (ui->lineEdit->text() != "1111") ui->lineEdit->setFocus();
}
So mask (an validator) doesn't work together with editingFinsihed signal.
plus i have tried this
bool MainWindow::eventFilter(QObject *filterObj, QEvent *event)
{
if (filterObj == ui->lineEdit ) {
if(event->type() == QEvent::FocusOut) {
if (ui->lineEdit->text() != "1111") { ui->lineEdit-`>setFocus();};
return true;
};
};
return false;
}
thank you Attila
From the Qt's doc:
Note that if there is a validator set on the line edit, the
returnPressed()/editingFinished() signals will only be emitted if the
validator returns QValidator::Acceptable.
But you can set a focus on every event, not only for FocusOut:
bool MainWindow::eventFilter(QObject *filterObj, QEvent *event)
{
if (filterObj == ui->lineEdit )
ui->lineEdit->setFocus();
if(event->type() == QEvent::KeyRelease)
{
QKeyEvent* e = (QKeyEvent*)event;
if(e->key() == Qt::Key_Return
|| e->key() == Qt::Key_Enter)
{
/* do what you want here */
}
}
return QObject::eventFilter(filterObj, event); // usual process other events
}

Can't catch TapAndHoldGesture

I grabGesture()ed one of my buttons:
buttons[0]->grabGesture(Qt::TapAndHoldGesture);
in the constructor, and declared:
bool event(QEvent *event);
in protected slots, and implemented it like this:
bool MyClass::event(QEvent *event)
{
if (event->type() == QEvent::Gesture){
QGestureEvent *gestevent = static_cast<QGestureEvent *>(event);
if (QGesture *gest = gestevent->gesture(Qt::TapAndHoldGesture)){
QTapAndHoldGesture *tapgest = static_cast<QTapAndHoldGesture *>(gestevent->gesture(Qt::TapAndHoldGesture));
cout << "grabbed a gesture event" << endl;
}
return true;
}
cout << "not a gesture event" << endl;
return QWidget::event(event);
}
and I keep getting "not a gesture event" printed to screen however I press (normal press / long press / ... )
What I'm trying to do is a long key press (from the keyboard)
It's said in the Qt Documentation:
A gesture could be a particular movement of a mouse, a touch screen
action, or a series of events from some other source. The nature of
the input, the interpretation of the gesture and the action taken are
the choice of the developer.
So I suppose also a keyboard can trigger QGesture events.
If the class handling the grap (MyClass) event is not the class where the gesture is detected on (QPushButton assuming buttons[0] is a QPushButton), then you need and event filter:
buttons[0]->grabGesture(Qt::TapAndHoldGesture);
buttons[0]->installEventFilter( myClass ); // myClass being a MyClass instance
Now, myClass object will be forwarded all events from buttons[0], this is done using QObject::eventFilter virtual function:
bool MyClass::eventFilter(QObject *obj, QEvent *event)
{
if ( event->type() == QEvent::Gesture && obj == buttons[0] )
{
QGestureEvent *gestevent = static_cast<QGestureEvent *>(event);
if (QGesture *gest = gestevent->gesture(Qt::TapAndHoldGesture)){
QTapAndHoldGesture *tapgest = static_cast<QTapAndHoldGesture *>(gestevent->gesture(Qt::TapAndHoldGesture));
cout << "grabbed a gesture event" << endl;
return true;
}
}
// standard event processing
return Parent::eventFilter(obj, event); // Parent being MyClass parent type, maybe QDialog or QWidget
}

QPlainTextEdit double click event

I need to capture the double click event on a QPlainTextEdit that is inside a QDockWidget.
In my actual code I have installed an event filter in the QDockWidget, to handle resize operations, and in the QPlainTextEdit, to handle the double click events:
// Resize eventfilter
this->installEventFilter(this);
ui->myPlainTextEdit->installEventFilter(this);
But, although it works for the QDockWidget I am unable to catch the double click event for the QPlainTextEdit:
bool MyDockWidget::eventFilter(QObject *obj, QEvent *event) {
if (event->type() == QEvent::Resize && obj == this) {
QResizeEvent *resizeEvent = static_cast<QResizeEvent*>(event);
qDebug("Dock Resized (New Size) - Width: %d Height: %d",
resizeEvent->size().width(),
resizeEvent->size().height());
} else if (obj == ui->myPlainTextEdit && event->type() == QMouseEvent::MouseButtonDblClick) {
qDebug() << "Double click";
}
return QWidget::eventFilter(obj, event);
}
With this code the message "Double click" is never shown. Any idea what is wrong with the code?
QTextEdit inherits a QScrollView and when you double click on the viewport of the QTextEdit, the viewport receives the double click event. You can cross check your current code by double clicking on the edges of the text edit. It will capture the event.
To solve this, add the event filter to the view port in addition to the current event filters you have installed as shown below:
ui->myPlainTextEdit->viewport()->installEventFilter(this);
Next, capture the event using this if statement:
if ((obj == ui->myPlainTextEdit||obj==ui->myPlainTextEdit->viewport()) &&
event->type() == QEvent::MouseButtonDblClick)
{
qDebug() << "Double click"<<obj->objectName();
}
You can capture the click position using QMouseEvent:
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
qDebug()<<QString("Click location: (%1,%2)").arg(mouseEvent->x()).arg(mouseEvent->y());

Force current index to be shown in QAbstractItemView even after losing focus

I have an instance of QAbstractItemView say QListView with selectionMode set to Qt::NoSelection. When I activate the widget, I can see the current index highlighted. However, when I focus another widget, the current index of the QListView is no longer highlighted. I need the current index to be highlighted all the time no matter what widget has focus.
You can do this with this event filter:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == ui->listView && event->type() == QEvent::FocusOut)
{
//when view loses focus we highlight current item
ui->listView->selectionModel()->select( ui->listView->currentIndex(), QItemSelectionModel::Select );
}
if (obj == ui->listView && event->type() == QEvent::FocusIn)
{
//when view gets focus we clear selection
ui->listView->selectionModel()->clear();
ui->listView->selectionModel()->select( ui->listView->currentIndex(), QItemSelectionModel::Select );
}
return QObject::eventFilter(obj, event);
}
To use eventFilter you should also:
protected:
bool eventFilter(QObject *obj, QEvent *event);//in header
and
qApp->installEventFilter(this);//in constructor
If you don't want to use event filter you can subclass view and reimplement focusInEvent ( QFocusEvent * event ) and focusOutEvent ( QFocusEvent * event ) and do same things.

How can I make a QWidget semitransparent to events?

I've seen similar questions but no answers that fit what I need. I want an invisible widget that lives on top of my whole application (no problems here). I want this widget to catch events so that I can print stuff about them, record them, whatever. I currently have an event filter hooked up that does this just fine. Then I want it to let the event go through to whatever is behind the widget. So for instance, if I try to push a button, the invisible widget should notice that a press happened on that spot, and then the button should actually be pressed. Can this be done in a simple way, or am I going to have to write code to simulate all the events beneath the invisible widget?
From all the information you disclosed in the comments, I suggest you filter the event as previously discussed, and then use QCoreApplication::sendEvent to forward the desired events to the invisible widget. It will then propagate the event accordingly to its children.
EDIT: OK, here is quick example that includes a QObject based event filter, that will filter the events for a widget, if the event is mouse event, it will be left for the widget to handle and print the output, if the event is a key event, it will be filtered and not forwarded back to the widget:
The event filter class:
class EventInfo : public QObject {
Q_OBJECT
public:
explicit EventInfo(QObject *parent = 0) : QObject(parent) {}
bool eventFilter(QObject *, QEvent *e) {
if (e->type() == QEvent::MouseButtonRelease){
qDebug() << "click event not filtered";
return false;
}
if (e->type() == QEvent::KeyRelease) {
QKeyEvent *event = static_cast<QKeyEvent *>(e);
if (event) qDebug() << "key" << event->key() << "filtered";
return true;
}
return false;
}
};
The widget:
class Widget : public QWidget {
Q_OBJECT
public:
Widget(QWidget *parent = 0) : QWidget(parent) {}
protected:
void mouseReleaseEvent(QMouseEvent *e) {
qDebug() << "widget clicked at position" << e->pos();
}
void keyReleaseEvent(QKeyEvent *e) {
qDebug() << "pressed key" << e->key();
}
};
main.cpp:
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
Widget w;
EventInfo info;
w.installEventFilter(&info);
w.show();
return a.exec();
}
Testing output to show that keyboard events are filtered and mouse press events are forwarded to the widget:
click event not filtered
widget clicked at position QPoint(352,230)
key 70 filtered
click event not filtered
widget clicked at position QPoint(405,163)
key 87 filtered

Resources