QT: Event for 'Up' and 'Down' arrows in QTimeEdit widget - c++

I am using Qt Creator 4.5.2 (Qt 5.9.5, GCC 7.3.0 64-bit) and running on Ubuntu 18.04.
I just customized the 'QTimeEdit' widget and it worked. Now, I need to intercept the event(s) for the 'Up' and 'Down' arrow (the arrow to change the current time). But, I don't know which event it is.
I already installed the 'evenFilter' and could catch all the events. I printed out all of them. But, I did not see an event trigger when I clicked the 'Up' or 'Down' arrow (The time did get changed). I assumed it was 'keyPressEvent' but apparently it was not since it did not trigger this method when I clicked the 'Up' or 'Down' arrow.
Any idea what events for the 'Up' or 'Down' arrow in the 'QTimeEdit' widget?
void MyTimeEdit::keyPressEvent(QKeyEvent *e)
{
qInfo() << "Key Press";
QTimeEdit::keyPressEvent(e);
}
bool MyTimeEdit::eventFilter(QObject *watched, QEvent *event)
{
if(watched == lineEdit())
qInfo() << "Event Type: " << event->type();
return QTimeEdit::eventFilter(watched, event);
}

If you click with the mouse then the event cannot be caused by a keyboard key.
In this case if you want to detect when you click on the "Up" or "Down" arrow of the QTimeEdit then you must use the mousePressEvent method:
#include <QApplication>
#include <QMouseEvent>
#include <QStyleOptionSpinBox>
#include <QTimeEdit>
#include <QDebug>
class TimeEdit: public QTimeEdit{
public:
using QTimeEdit::QTimeEdit;
protected:
void mousePressEvent(QMouseEvent *event){
QTimeEdit::mousePressEvent(event);
QStyleOptionSpinBox opt;
initStyleOption(&opt);
QStyle::SubControls control = style()->hitTestComplexControl(
QStyle::CC_SpinBox, &opt, event->pos(), this);
if(control == QStyle::SC_SpinBoxUp)
qDebug() << "up";
else if (control == QStyle::SC_SpinBoxDown) {
qDebug() << "down";
}
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TimeEdit w;
w.show();
return a.exec();
}
But keep in mind that not only the clicks do change the value of what the QTimeEdit shows but also the keyboard, the wheel, etc., so if you want to cover all those cases it is better to track override the stepBy() method
#include <QApplication>
#include <QTimeEdit>
#include <QDebug>
class TimeEdit: public QTimeEdit{
public:
using QTimeEdit::QTimeEdit;
void stepBy(int steps){
qDebug() << steps;
QTimeEdit::stepBy(steps);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TimeEdit w;
w.show();
return a.exec();
}

Related

Coloring a specific line (indicated by the cursor) in textedit for QT , but the cursor's position changes with a function every time button is pressed

I edited it like this. But all text is not printed in textEdit even though the word is added to the correct position and colored.
ui->textEdit->setText(display_text);
QTextcursor cursor=ui->textEdit->textCursor();
cursor.movePosition(QTextCursor::Right,QTextCursor::MoveAnchor,cursor_position);
cursor.insertHtml("<span style=color:red;>"+coloring_string+"</span>");
ui->textEdit->setTextCursor(cursor);
You have to use setExtraSelections:
#include <QApplication>
#include <QTextEdit>
class Editor: public QTextEdit {
public:
Editor(QWidget *parent=nullptr): QTextEdit(parent){
connect(this, &QTextEdit::cursorPositionChanged, this, &Editor::highlightCurrentLine);
highlightCurrentLine();
}
private:
void highlightCurrentLine(){
QList<QTextEdit::ExtraSelection> extraSelections;
if (!isReadOnly()) {
QTextEdit::ExtraSelection selection;
QColor lineColor("red");
selection.format.setBackground(lineColor);
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
selection.cursor = textCursor();
selection.cursor.clearSelection();
extraSelections.append(selection);
}
setExtraSelections(extraSelections);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyle("fusion");
Editor editor;
editor.resize(640, 480);
editor.show();
return a.exec();
}

How to prevent default context menu on QGraphicsTextItem?

Is it possible to prevent right-click from opening the default context menu on QGraphicsTextItem ? The menu with "Undo, Redo, Cut, Copy, Paste..". On Ubuntu 18.04, that is. I don't know how this behaves on Windows.
I have overridden the mouse press handler to eat right-clicks in my view and tried to do that also in the item class itself. This actually did prevent the menu on Qt 5.10.0, but for some reason not anymore on 5.11.1:
void EditorView::mousePressEvent(QMouseEvent * event)
{
if (event->button() == Qt::RightButton)
{
return;
}
...
doOtherHandlingStuff();
...
}
In the item itself it doesn't have any effect if I do this:
void TextEdit::mousePressEvent(QGraphicsSceneMouseEvent * event)
{
event->ignore();
return;
}
You have to override the contextMenuEvent method of QGraphicsTextItem:
#include <QtWidgets>
class GraphicsTextItem: public QGraphicsTextItem
{
public:
using QGraphicsTextItem::QGraphicsTextItem;
protected:
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override
{
event->ignore();
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
QGraphicsView w{&scene};
auto it = new GraphicsTextItem("Hello World");
it->setTextInteractionFlags(Qt::TextEditable);
scene.addItem(it);
w.show();
return a.exec();
}

Debounce event filter in Qt

it's my first question here about Qt (usually internet and doc helps me alot)
I've installed a eventfilter on my app (in main.cpp), and I want this event filter to check the key pressed then redistribute it to lower functions (like moving an item on a QGraphicsScene),
This is working BUT, 5 times..
The qDebug() in filter shows me that the key is pressed 5 times when it was just one.
Event filter is so fast it catches it 5 times.
Can't find a way to debounce that.
Here's the interesting parts of code:
main.cpp
#include "mainwindow.h"
#include "eventfilter.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
xEventFilter *filter = new xEventFilter(&a);
a.installEventFilter(filter);
xMainWindow w;
w.show();
return a.exec();
}
eventfilter.h
#ifndef EVENTFILTER_H
#define EVENTFILTER_H
#include <QObject>
class xEventFilter : public QObject
{
Q_OBJECT
public:
explicit xEventFilter(QObject *parent = nullptr);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
};
#endif // EVENTFILTER_H
eventfilter.cpp
#include "eventfilter.h"
#include "editor.h"
#include <QKeyEvent>
#include <QDebug>
extern xEditor *editor;
xEventFilter::xEventFilter(QObject *parent) :
QObject(parent)
{ }
bool xEventFilter::eventFilter(QObject *obj, QEvent *event)
{
qDebug() << "Enter filter";
if (event->type() != QEvent::KeyPress)
return QObject::eventFilter(obj, event);
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
qDebug() << keyEvent->text();
switch(keyEvent->key()) {
case Qt::Key_Z: { editor->selection->moveSelection(keyEvent); }
case Qt::Key_S: { editor->selection->moveSelection(keyEvent); }
case Qt::Key_Q: { editor->selection->moveSelection(keyEvent); }
case Qt::Key_D: { editor->selection->moveSelection(keyEvent); }
case Qt::Key_Space: { }
}
return false;
}
Looking up to your answers ;)
The main issue is that even if you handle the event, you return false. According to the documentation, you should return true if you want the event to stop being handled.
In your reimplementation of this function, if you want to filter the
event out, i.e. stop it being handled further, return true; otherwise
return false.
Also, you're missing break in cases of your switch statement.

How to disable shortcuts for QComboBox in qt?

I searched for the answers online, but I did not really find one that solved my problem. My question is like: I have a QComboBox, let's say I added three items to this:
ui->comboBox->addItem("First");
ui->comboBox->addItem("Second");
ui->comboBox->addItem("Third");
Then if I press the S on the keyboard, the item will change to Second, if I press T, so item will just change to Third. How can I disable this?
A possible solution is to implement an eventfilter that prevents the letters from being used in the QComboBox:
#include <QApplication>
#include <QComboBox>
#include <QKeyEvent>
class Helper: public QObject{
QComboBox *m_combo;
public:
using QObject::QObject;
void setComboBox(QComboBox *combo){
m_combo = combo;
m_combo->installEventFilter(this);
}
bool eventFilter(QObject *watched, QEvent *event){
if(m_combo){
if(m_combo == watched && event->type() == QEvent::KeyPress){
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
if(!ke->text().isEmpty())
return true;
}
}
return QObject::eventFilter(watched, event);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QComboBox w;
w.addItems({"First", "Second","Third"});
Helper helper;
helper.setComboBox(&w);
w.show();
return a.exec();
}

Qt: cursor blinking cause repaint of parent widget?

Bellow you can see minimal example code to demonstrate problem.
If you run it and give focus to QLineEdit, you get output every second: paintEvent, paintEvent and so on.
I can not understand why MyW::paintEvent called on every
cursor blinking in child widget? As you see I do not configure QLineEdit,
by default on my linux box it have no transparent elements,
but still for some reason cursor cause all widgets to redraw their content?
#include <QApplication>
#include <QWidget>
#include <QPaintEvent>
#include <QPainter>
#include <QLineEdit>
class MyW final : public QWidget {
public:
MyW() {
//setAutoFillBackground(false);
}
void paintEvent(QPaintEvent *e) {
e->accept();
qDebug("paintEvent");
QPainter painter{this};
painter.fillRect(rect(), Qt::green);
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyW w;
w.resize(600, 600);
w.show();
auto le = new QLineEdit{&w};
le->show();
return app.exec();
}