Qt wheelEvent over all - qt

I have app window with many layouts and widget. I have also scrollarea with switch-off scrollbars. I am able to create slots for scrollareaup and scrollareadown. But when I create wheelEvent for all App it's working only for items int app NOT in scrollarea. When I just try this:
void TContic_win::wheelEvent(QWheelEvent *event) {
cout << "-" << endl;
}
I don't know how I can fix it. My idea is something like:
bool TContic_win::eventFilter(QObject *obj, QEvent *e) {
if (isChildOfScrollWidget(obj) { if (e == wheel) scroll Up or Down }
}

You may do something like this (in case if your widgets have Your_Scrol_Widget as parent):
void TContic_win::wheelEvent(QWheelEvent *we)
{
if (this->childAt( we->pos() )->parent() == Your_Scrol_Widget)
qDebug() << "-" ;
}
You must got an idea.

I am sorry. It's my mistake. I had a wrong event filter. I used 'return true' in bad conditions so due to this mistake I was always ignore other events and my event filter doesn't work over child items. By the way, thanks for your effort.

Related

Touch freeze in QtWebEngine after opening a DropDown menu

I stumbled across a QtWebEngine problem while using a touch display. I can browse through all websites via my touch display, but when I click on a DropDown menu (for example on https://www.ebay.com/ clicking on "All categories" next to the search field), touch is not working anymore (or 1/30 touch clicks works). I can still close it via mouse/keyboard. After closing the DropDown menu, touch is working again.
I created a small example browser:
BrowserWidget::BrowserWidget(QWidget *parent)
: QWidget(parent), ui(new Ui::BrowserWidget),
m_webView(new QWebEngineView(this)), m_page(new QWebEnginePage(this)) {
ui->setupUi(this);
ui->verticalLayout->addWidget(m_webView);
m_page->setUrl(QUrl(QStringLiteral("https://www.ebay.com/")));
m_webView->setPage(m_page);
m_webView->setAttribute(Qt::WA_AcceptTouchEvents);
m_webView->installEventFilter(this);
}
bool BrowserWidget::eventFilter(QObject *watched, QEvent *e) {
qDebug() << "event: " << e->type();
if (e->type() == QEvent::ChildAdded) {
QChildEvent *ce = static_cast<QChildEvent *>(e);
if (ce && ce->child()) {
ce->child()->installEventFilter(this);
}
}
return false;
}
I installed my event filter to the widgets in the QEvent::ChildAdded for a better debugging (so I can observe more events).
This behaviour is always reproducable and I don't know if I did something wrong, because I can operate the browser via touch. I also added the Qt::WA_AcceptTouchEvents to the child widgets, but it didn't make any difference.
I hope somebody of you can help me out, thank you!
Found out that it is a Qt-bug
https://bugreports.qt.io/browse/QTBUG-79254
I created a workaround for this problem, maybe somebody needs this in the future:
bool WebEngineView::event(QEvent *e)
{
// Workaround for QTBUG-79254: DropDown-menus are not accepting any touchevents
if (e->type() == QEvent::ChildAdded) {
QChildEvent *ce = static_cast<QChildEvent *>(e);
if (ce && ce->child() && ce->child()->isWidgetType()) {
QWidget *child = static_cast<QWidget *>(ce->child());
if (child->windowFlags() & Qt::Popup) {
Qt::WindowFlags flags = child->windowFlags();
flags = flags & (~Qt::Popup) | Qt::Dialog;
child->setWindowFlags(flags);
}
}
}
return QWebEngineView::event(e);
}

Qt QMouseEvent class

I'm kind of new to the Qt Framework and was trying to program a game and realised there is no signal for "rightclick()". I read through the documentation and found out I had to use the "QMouseEvent" class but I just can't figure out how it works.. Somebody help me.
Use Qt::MouseButtons QMouseEvent::buttons() const.
It returns, according to Qt documentation:
Returns the button state when the event was generated. The button state is a combination of Qt::LeftButton, Qt::RightButton, Qt::MidButton using the OR operator
So All you need to do is:
void mouseMoveEvent(QMouseEvent *e) {
if(e->buttons() == Qt::RightButton)
qDebug() << "The right button was clicked";
}

Ignore keyboard presses on Qt inside OSG

I’m newbie with Qt, and experiencing one problem I cannot deal with for, like, a month. The situation is like this:
I’ve OpenSceneGraph project (which is OpenGL) and trying to make Qt interface inside the 3d scene. I think its not necessary how I deal with that, but if someone wants to know more here is thread with more info on OSG forum (though I didnt get solution there). The problem is, when any key on keyboard is clicked, Qt controls jump around the screen and dont react on any (mouse or keyboard) events anymore. The entire program continues to work, though.
To summarize, my question is like: is there a way to make Qt widgets ignore all keypresses?
I’ve searched a lot, but couldnt find any working solution.
Thanks in advance!
Read a bit about events in Qt. There is a section about event filtering (but please don't jump straight to it :P).
SHORT ANSWER :
void Qwidget::setEnabled ( bool );
The drawback is that it disable also mouse events, change the widget style and that's a bummer.
LONG ANSWER : FILTER EVENTS
One possibility is to filter all events on the Qt application. I suppose the function which launch your Qt code looks like this (if different post here):
int main(int argc, char* argv[]){
QApplication app(argc, argv);
QWidget toplevelwidget1;
toplevelwidget1.show()
//stufff
return app.exec();
}
//doesnt have to exactly like this.
you can to set an event filter on app variable. It is the more elegant solution but it is too complicated because it filters native events and will require some work...
What you can do instead is filter only your top level widgets or windows (the one without parents). You define an event filter (which is a QObject) like :
class KeyboardFilter: public QObject
{
Q_OBJECT
...
protected:
bool eventFilter(QObject *obj, QEvent *event);
};
bool KeyboardFilter::eventFilter(QObject *obj, QEvent *event)
{
//for all events from keyboard, do nothing
if (event->type() == QEvent::KeyPress ||
event->type() == QEvent::KeyRelease ||
event->type() == QEvent::ShortcutOverride ||
) {
return true;
} else {
// for other, do as usual (standard event processing)
return QObject::eventFilter(obj, event);
}
}
Then you set the filter on the desired widgets using:
myDesiredWidgetorObject->installEventFilter(new KeyboardFilter(parent));
And that's it!

Getting MouseMoveEvents in Qt

In my program, I'd like to have mouseMoveEvent(QMouseEvent* event) called whenever the mouse moves (even when it's over another window).
Right now, in my mainwindow.cpp file, I have:
void MainWindow::mouseMoveEvent(QMouseEvent* event) {
qDebug() << QString::number(event->pos().x());
qDebug() << QString::number(event->pos().y());
}
But this seems to only be called when I click and drag the mouse while over the window of the program itself. I've tried calling
setMouseTracking(true);
in MainWindow's constructor, but this doesn't seem to do anything differently (mouseMoveEvent still is only called when I hold a mouse button down, regardless of where it is). What's the easiest way to track the mouse position globally?
You can use an event filter on the application.
Define and implement bool MainWindow::eventFilter(QObject*, QEvent*). For example
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseMove)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
statusBar()->showMessage(QString("Mouse move (%1,%2)").arg(mouseEvent->pos().x()).arg(mouseEvent->pos().y()));
}
return false;
}
Install the event filter when the MainWindows is constructed (or somewhere else). For example
MainWindow::MainWindow(...)
{
...
qApp->installEventFilter(this);
...
}
I had the same problem, further exacerbated by the fact that I was trying to call this->update() to repaint the window on a mouse move and nothing would happen.
You can avoid having to create the event filter by calling setMouseTracking(true) as #Kyberias noted. However, this must be done on the viewport, not your main window itself. (Same goes for update).
So in your constructor you can add a line this->viewport()->setMouseTracking(true) and then override mouseMoveEvent rather than creating this filter and installing it.

Get a notification/event/signal when a Qt widget gets focus

In Qt, when a widget receives focus, how can get a notification about it, so I can execute some custom code? Is there a signal or an event for that?
You can add en event filter.
This is an example of an application written with QtCreator. This form has a QComboBox named combobox.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->comboBox->installEventFilter(this);
.
.
.
}
bool MainWindow::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::FocusOut)
{
if (object == ui->comboBox)
{
qWarning(object->objectName().toLatin1().data());
}
}
return false;
}
There is a "focusChanged" signal sent when the focus changes, introduced in Qt 4.1.
It has two arguments, he widget losing focus and the one gaining focus:
void QApplication::focusChanged(QWidget * old, QWidget * now)
Qt Designer isn't designed for this level of WYSIWYG programming.
Do it in C++:
class LineEdit : public QLineEdit
{
virtual void focusInEvent( QFocusEvent* )
{}
};
The simplest way is to connect a slot to the QApplication::focusChanged signal.
I'd have to play with it, but just looking at the QT Documentation, there is a "focusInEvent". This is an event handler.
Here's how you find information about.... Open up "QT Assistant". Go to the Index. Put in a "QLineEdit". There is a really useful link called "List of all members, including inherited members" on all the Widget pages. This list is great, because it even has the inherited stuff.
I did a quick search for "Focus" and found all the stuff related to focus for this Widget.
You have hit on of the weird splits in QT, if you look at the documentation focusInEvent is not a slot it is a protected function, you can override it if you are implementing a subclass of your widget. If you you just want to catch the event coming into your widget you can use QObject::installEventFilter it let's you catch any kind of events.
For some odd reason the developers of Trolltech decided to propagate UI events via two avenues, signals/slots and QEvent
Just in case anybody looking for two QMainWindow focus change .
You can use
if(e->type() == QEvent::WindowActivate)
{
//qDebug() << "Focus IN " << obj << e ;
}
QWidget::setFocus() is slot, not signal. You can check if QLineEdit is in focus with focus property. QLineEdit emits signals when text is changed or edited, see documentation.

Resources