check when a button is clicked event qt - c++

I am a beginner in Qt and I would like to know, how can I create an event which checks when a button in the windows gets clicked? The window has a single push button.
I could not find a simple and correct example for my question, that's why I am asking here. I did google first.
Thank you

class MyClass : public QWidget
{
public:
MyClass ()
{
QPushButton *pButton = new QPushButton(this);
QObject::connect(pButton, &QPushButton::clicked, this, &MyClass::onButtonClicked);
}
public slots:
void onButtonClicked () {qDebug () << "Button clicked";};
};
onButtonClicked will be called if the button pressed.
Please see signals & slots and QPushButton signals for more information.

Qt employs the signals and slots paradigm. You don't check if a button is clicked. When a button is clicked, it emits a signal. You can connect your own functions to that signal. So whenever that button is clicked, the signal is emitted, and triggers all the functions it is connected to.
Be sure to check out signals and slots, which is a core concept of Qt, along with properties and meta data.
Note that as a QWidget derived, a button comes with the following methods, which are triggered by mouse events and you can override them if you wish, although in the case of something as a button that is hardly necessary:
virtual void mouseDoubleClickEvent(QMouseEvent * event)
virtual void mouseMoveEvent(QMouseEvent * event)
virtual void mousePressEvent(QMouseEvent * event)
virtual void mouseReleaseEvent(QMouseEvent * event)

Related

Qt mouse events not working in QGraphicsScene

I am using Qt 5.7 (the latest version). I can't get the mouse events to work in QGraphicsScene, but they work in window outside of my scene. I have followed this question.
So I have overwritten QWidget::mouseMoveEvent() in my main widget's subclass like this:
// header:
class MyWidget {
...
void mouseMoveEvent( QMouseEvent * event );
};
// source:
MyWidget::MyWidget() {
setMouseTracking();
}
void MyWidget::mouseMoveEvent( QMouseEvent * event ) {
}
It doesn't work for: mouseMoveEvent, mouseGrabber, mousePressEvent, mouseReleaseEvent, or mouseDoubleClickEvent. But somehow it only works for mousePressEvent.
Could this be a bug in Qt?
SOURCE CODE:
In objectloader.cpp
ObjectLoader::ObjectLoader(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::ObjectLoader)
{
ui->setupUi(this);
scene=new QGraphicsScene(this);
ui->graphicsView->setScene(scene);
ui->graphicsView->setMouseTracking(true);
setMouseTracking(true);
}
Thats were i set mouse tracking twice
In objectloader.h
Then i define that method in objectloader.h
class ObjectLoader : public QMainWindow
{
Q_OBJECT
public:
explicit ObjectLoader(QWidget *parent = 0);
~ObjectLoader();
private slots:
void mouseMoveEvent(QMouseEvent *event);
protected:
private:
};
#endif // OBJECTLOADER_H
And implementation of that method in objectloader.cpp
void ObjectLoader::mouseMoveEvent(QMouseEvent *event){
qDebug()<<"Mouse moved";
}
When a mouse event is generated by Qt it is generally passed initially to the QWidget that was under the mouse pointer when the event was generated. If that QWidget accepts the event then no further processing will take place. If the event isn't accepted then Qt may propogate the event to that QWidget's parent and so on.
In your particular case the mouse move events you are interested in are being sent to the QGraphicsView/QGraphicsScene conponents where they are being accepted and, hence, no further processing takes place. In a case like that you generally need to install an event filter to intercept and process the events of interest.
Mouse move events will occur only when a mouse button is pressed down, unless mouse tracking has been enabled with QWidget::setMouseTracking().
So, I think you should check whether mouseTracking is really enabled or not, by using `bool hasMouseTracking() const'.

how to connect function between two classes

I have two different class in two files:
class Game: public QGraphicsView()
class Window: public QMainWindow()
{
public: Window();
Game *game;
public slots: void test() {game = new Game();};
}
in Window.cpp I start a new Game using test() function:
Window::Window() {test();}
now in Game.cpp I create a QMessageBox with two QPushButton
QMessageBox *box= new QMessageBox();
QPushButton *btYES = box->addButton(tr("YES"),QMessageBox::ActionRole);
QPushButton *btNO = box->addButton(tr("NO"),QMessageBox::ActionRole);
box->exec();
if (box->clickedButton() == btYES) {Window::test();}
if (box->clickedButton() == btNO) {close();}
As you can see I want to connect the function test() to btYES inside the Game.cpp but that function is inside Window.cpp and its function is to start a new game.
It is possible to do so?
QPushButton emits events when it its pressed/released
So you could connect the, lets say, released signal to a slot:
connect(button, SIGNAL(released()), windowClass, SLOT(handleButton()));
In your case you need to send it across classes, so you may need to do it in two steps.
In game:
// connect the button to a local slot
connect(btYES, SIGNAL(released()), this, SLOT(handleYesButton()));
// in the slot emit a signal - declare the signal in the header
game::handleYesButton()
{
emit userChoiceYes();
}
In window
// connect the signal in game to a your slot:
connect(game, SIGNAL(userChoiceYes()), this, SLOT(test()));
Then when btnYes is pressed/released the signal released is emitted - you pick that up in handleYesButton() and emit your own signal which your window class is connected to and handles it in test()
Based on #code_fodder answer, but you don't even need another slot, plus the basic signal for a QPushButton is clicked(). Here's the documentation :
A push button emits the signal clicked() when it is activated by the
mouse, the Spacebar or by a keyboard shortcut. Connect to this signal
to perform the button's action. Push buttons also provide less
commonly used signals, for example pressed() and released().
To start, instead of adding another slot in your class Game, just connect the button's signal clicked() to another signal :
connect(btYES, SIGNAL(clicked()), this, SIGNAL(btYesClicked()));
The signal from the class Game is now emitted when you press the button btYes. Now, you just have to connect this signal to a slot test() in your class Window :
connect(game, SIGNAL(btYesClicked()), this, SLOT(test()));

Qt : catched mouseMoseEvent dont interact with QWebView html page element

I catch the mouseMoveEvent of my QWebView for restarting a timer of a screensaver. The problem is that now the mouseMoveEvent isnt distribued to the HTML elements so its impossible for example to move a sliding bar on the page.
I use connect to bind mouseMoveEvent to the restart slot :
QObject::connect(_view, SIGNAL(mouseMoveEvent(QMouseEvent*)), _mediaPlayer, SLOT(stop()));
WebView class :
class WebView : public QWebView
{
Q_OBJECT
public:
WebView(QString menu) : _menuDesc(menu) {};
WebView(){};
void setMenuDesc(QString menu) {_menuDesc = menu;};
QString getMenuDesc() {return _menuDesc;};
void setCurrPage(QString page) {_currPage = page;};
QString getCurrPage() {return _currPage;};
void setCurrCategory(QString page) {_currPage = page;};
QString getCurrCategory() {return _currPage;};
void mouseMoveEvent(QMouseEvent *)
{
emit mouseMoved();
};
signals :
void mouseMoved();
private:
QString _menuDesc = 0;
QString _currPage;
QString _currCategory = 0;
};
Is there a solution to still catch the signal and pass it to the HTML page?
mouseMoveEvent is not a signal but an event handler. You can reimplement this event handler and let it emit a signal you can connect to if you need that.
Like this:
MyWebView::mouseMoveEvent(QMouseEvent * e) {
emit mouseMoved(); // this would be signal you could connect to.
}
Seems you misunderstand event handler and signal usages.
mouseMoveEvent is a member method of QWidget, is not a signal so you cannot connect to it. You can override it in you subclass and emit your own signal.
And if a QWidget's mouse tracking is switched off, mouse move events only occur if a mouse button is pressed while the mouse is being moved. Maybe you need to call setMouseTracking too.

itemDoubleClicked signal is not emitted when mouseDoubleClickEvent is implemented

I'm implementing a class that inherits the QTreeWidget,
I'm trying to do something only when the user left-clicks on an item.
Since itemDoubleClicked only gives you the item and not the mouse event,
and mouseDoubleClickEvent only gives you the mouse event with no item,
so I thought I would add a member in the class and record whether left or right button was pressed in mouseDoubleClickEvent,
then check that info when entering the slot connected to signal itemDoubleClicked.
That is, if the signal is emitted after the event handler. I was planning on experimenting if this was true, but then I ran into this issue.
Ok, back to the class, it looks something like this:
class myTreeWidget : public QTreeWidget{
Q_OBJECT
private:
Qt::MouseButton m_button;
public:
myTreeWidget(QWidget* parent):QTreeWidget(parent){
m_button = Qt::NoButton;
connect(this, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
this, SLOT(slot_doubleClick(QTreeWidgetItem*,int)));
}
void mouseDoubleClickEvent(QMouseEvent* event){
m_button = event->button();
}
public slots:
void slot_doubleClick(QTreeWidgetItem* item, int column);
signals:
void itemDoubleClicked(QTreeWidgetItem* item, int column);
}
Yep, something like this.
Then I used gdb to check which was called first,
mouseDoubleClickEvent or slot_doubleClick,
and it turns out that slot_doubleClick was not called at all.
I commented out mouseDoubleClickEvent and tried again,
and slot_doubleClick was called.
So um... what I'm asking here is...
is this a limitation in Qt?
Can I only choose one between signals&slots and event handlers?
Or am I just doing it wrong?
Moreover, if this is a limitation,
can you recommend another solution to what I'm trying to do?
(only respond to left double-clicks)
Sorry for the long post and thanks!
If you override some event handler and want also default behavior, you should call base handler implementation. For example try this:
void mouseDoubleClickEvent(QMouseEvent* event){
m_button = event->button();
QTreeWidget::mouseDoubleClickEvent(event);
}

Is it possible to track if QLineEdit was clicked on?

What does the documentation say
QPushButton has a clicked() signal so one can do something like this
connect(ui->Btn,SIGNAL(clicked()),this,SLOT(DoSmth()));
QLineEdit has a textEdited() signal that allows to track the edit action.
What I am trying to achieve
I'm trying to run a function when a QLineEdit was just clicked on, not edited. Is that possible?
You can subclass QLineEdit and reimplement QWidget::focusInEvent, where you can check if the reason of the focus was mouse click. Then use this subclass instead of QLineEdit. You may create a custom signal and emit it from this event handler too to be able to use it through signal/slots.
#include <QLineEdit>
#include <QFocusEvent>
class FocusHandlerLineEdit : public QLineEdit
{
Q_OBJECT
protected:
void focusInEvent(QFocusEvent * event) {
QLineEdit::focusInEvent(event);
if(event->reason() == Qt::MouseFocusReason)
emit gotFocus();
}
signals:
void gotFocus();
};