mousePressEvent(QMouseEvent *event) not working for QComboBox in Qt - qt

Ok, so I implemented the function following function:
CommandInput is a class which inherits the class QComboBox.
void CommandInput::dragEnterEvent(QDragEnterEvent *event)
{
qDebug() << "Proposed drop " << event->mimeData()->formats();
event->acceptProposedAction();
}
and it is working fine.
But the problem is my following function is not working , in fact when I click mouse button, nothing gets printed, Why is that?
void CommandInput::mousePressEvent(QMouseEvent *e)
{
qDebug()<<"X IS"<<e->pos().x();
}

Related

Leave event not called when hiding a widget

I wants to hide a QLabel widget when the mouse is released on it. Everything works fine, except that the leaveEvent is not called when I call QLabel::hide(), inside mouseReleaseEvent.
The method is called properly when I leave the label normally (while it is shown), but not when I call the hide() method. I tried to call hide() outside the mouseReleaseEvent (using a QTimer), but leaveEvent is still not called.
The result is that when I display the label again, enterEvent is not called the first time the mouse enter the widget, and I have to move outside (to call leaveEvent), and then inside again.
So my question is why leaveEvent is not called when I hide the label (the mouse is still over the widget), and is there a way to force the call of leaveEvent whenever I want.
I hope my explanations are not too confused. Thanks.
Edit:
Here is a simple example that doesn't work for me:
struct Label : public QLabel
{
Label(QGraphicsScene *scene)
{
item.setWidget(this);
setText("Text");
scene->addItem(&item);
setMinimumWidth(200);
setMinimumHeight(200);
show();
}
~Label()
{
item.setWidget(NULL);
}
void mousePressEvent(QMouseEvent *)
{
}
void mouseReleaseEvent(QMouseEvent *)
{
std::cout << "mouseReleaseEvent" << std::endl;
hide();
}
void enterEvent(QEvent *)
{
std::cout << "Enter" << std::endl;
}
void leaveEvent(QEvent *)
{
std::cout << "Leave" << std::endl;
}
QGraphicsProxyWidget item;
};

Create and specify a QLabel after mouse pressed on another QLabel in QT

Ok so what i'm trying to do is to create a new QLabel added to a QList and put it where I clicked on the other QLabel where I clicked.
So here is my code:
class CustomLabel : public QLabel
{
Q_OBJECT
public:
CustomLabel();
void mousePressEvent( QMouseEvent* event);
private:
QList<QLabel *> pointsL;
QList<QPoint *> points;
};
void CustomLabel::mousePressEvent(QMouseEvent *event)
{
points << new QPoint(event->pos());
pointsL << new QLabel(this);
pointsL.at(pointsL.size()-1)->setText("+");
pointsL.at(pointsL.size()-1)->setGeometry(QRect(points.at(points.size()-1)->rx(),, points.at(points.size()-1)->ry(), 1, 1));
}
I also tried:
pointsL.at(pointsL.size()-1)->move(points.at(points.size()-1)->rx(), points.at(points.size()-1)->ry());
and this:
void CustomLabel::mousePressEvent(QMouseEvent *event)
{
points << new QPoint(event->pos());
pointsL << new QLabel(this);
pointsL.at(pointsL.size()-1)->setText("+");
pointsL.at(pointsL.size()-1)->move(*points.at(points.size()-1));
pointsL.at(pointsL.size()-1)->setTabOrder(pointsL.at(pointsL.size()-1), this);
}
When I click on the Custom Label nothing happens. The constructor is empty.
Thanks for any answer.
New widgets added after the parent is already visible on screen should be shown explicitly unless they are in a layout.
So basically you should add:
pointsL.back()−>show();

Qt rightclick QPushButton

I'm using Qt Creator to create a gui for a mineseeper game.
How can I know a QpushButton clicked with rightclick? for flag in the game.
In other word, which signal used for rightclick?
Create your own button with filter at mousePressEvent slot.
qrightclickbutton.h
#ifndef QRIGHTCLICKBUTTON_H
#define QRIGHTCLICKBUTTON_H
#include <QPushButton>
#include <QMouseEvent>
class QRightClickButton : public QPushButton
{
Q_OBJECT
public:
explicit QRightClickButton(QWidget *parent = 0);
private slots:
void mousePressEvent(QMouseEvent *e);
signals:
void rightClicked();
public slots:
};
#endif // QRIGHTCLICKBUTTON_H
qrightclickbutton.cpp
#include "qrightclickbutton.h"
QRightClickButton::QRightClickButton(QWidget *parent) :
QPushButton(parent)
{
}
void QRightClickButton::mousePressEvent(QMouseEvent *e)
{
if(e->button()==Qt::RightButton)
emit rightClicked();
}
Now connect like this
QRightClickButton *button = new QRightClickButton(this);
ui->gridLayout->addWidget(button);
connect(button, SIGNAL(rightClicked()), this, SLOT(onRightClicked()));
Create a slot in MainWindow.cpp.
void MainWindow::onRightClicked()
{
qDebug() << "User right clicked me";
}
It works for me!
I think QPushButton is internally implemented to listen to left mouse clicks only. But you can easily extend QPushButton and re-implement let's say the mouse release event and do your thing if the right mouse button was pressed, e.g. emit a custom rightClicked() signal for example:
signals:
void rightClicked();
protected:
void mouseReleaseEvent(QMouseEvent *e) {
if (e->button() == Qt::RightButton) emit rightClicked();
else if (e->button() == Qt::LeftButton) emit clicked();
}
... or you can create an overload of the clicked signal that forwards the mouseEvent pointer so you can do the same check outside of the button.
signals:
void clicked(QMouseEvent *);
protected:
void mouseReleaseEvent(QMouseEvent *e) {
emit clicked(e);
}
Then you do the check in the slot you connect the button's clicked(QMouseEvent *) signal to and proceed accordingly.
I just wrote this little helper adapter to make any existing button right-clickable with no need to subclass it:
class CRightClickEnabler : public QObject
{
public:
CRightClickEnabler(QAbstractButton * button): QObject(button), _button(button) {
button->installEventFilter(this);
};
protected:
inline bool eventFilter(QObject *watched, QEvent *event) override {
if (event->type() == QEvent::MouseButtonPress)
{
auto mouseEvent = (QMouseEvent*)event;
if (mouseEvent->button() == Qt::RightButton)
_button->click();
}
return false;
}
private:
QAbstractButton* _button;
};
Usage:
connect(ui->pushButton, &QPushButton::clicked, [](){qDebug() << "Button clicked";});
new CRightClickEnabler(ui->pushButton);
From now on, the clicked signal will be triggered by the right click as well as left click. There's no need to delete this object - it uses ui->pushButton as parent and will be auto-deleted by Qt when the parent is destroyed.
Obviously, you can write 2 lines of code (literally) to declare a new signal here and emit that signal upon right click instead of clicked, if desired.
I'd like to suggest this option as well, without need for event filter/other stuffs...
self.button.released.connect(self.doStuff)
self.button.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.button.customContextMenuRequested.connect(partial(self.doStuff, False))
def doStuff(self,state=True,p=QPoint()):
print("True for left, False for right!",state)

selecting the complete default text by a mouse click

I have a QLineEdit widget in my menubar which shows the text "search by ID" by default. How can I implement a MouseClicked event handler for the QLineEdit, such that when I click on the LineEdit widget, the default text is cleared and user can enter the text that he wants to search?.
so far
#ifndef SEARCH_H
#define SEARCH_H
#include<QLineEdit>
class search : public QLineEdit
{
signals:
void clicked();
protected:
void mousePressEvent(QMouseEvent *);
};
#endif
You just need to connect QLineEdit::mousePressEvent ( QMouseEvent * e ) signal with function. When this signal will be emited, clear QLineEdit in your function. Simply, isn't it?
EDIT
Or if u have
void mousePressEvent(QMouseEvent *);
in your widget, all what you need is write definition for that method. When user press mouse over QLineEdit, this function will be invoked. Like:
void search::mousePressEvent(QMouseEvent *e)
{
myQLineEdit->setText("");
}
EDIT 2
Then try to do it this way:
class YourWidget : public QLineEdit
{
Q_OBJECT
protected:
void focusInEvent(QFocusEvent* e);
};
and
void YourWidget::focusInEvent(QFocusEvent* e)
{
if (e->reason() == Qt::MouseFocusReason)
{
myQLineEdit->setText("");
}
// You might also call the parent method.
QLineEdit::focusInEvent(e);
}
You'll want to use the QLineEdit::placeholderText property. It shows a grey text which disappears when the user starts editing it (i.e. when it gains focus).
QLineEdit * edit = new QLineEdit;
edit->setPlaceholderText("Search by ID");

MousePressEvent in view and items in Qt

I have a custom QGraphicsView and a custom QGraphicsItem. I want the Item to handle my click if I click in the item, else I want the click to be handled by the View.
But when I click on the item, the item handles the click. This is ok. But if I click somewhere else the click isn't handled at all. All the code in my classes that have anything to do with mouseEvents is below.
class CustomView : public QGraphicsView
{
Q_OBJECT
public:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
};
void CustomView::mousePressEvent(QGraphicsSceneMouseEvent *event){
cout << "pressing in view";
}
class CustomItem : public QGraphicsItem
{
public:
CustomItem(CustomView* widget)
void mousePressEvent(QGraphicsSceneMouseEvent *event);
};
CustomItem::CustomItem(CustomView* widget){
setFlag(ItemIsSelectable);
setFlag(ItemIsMovable);
}
void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event){
cout << "pressing in item";
}
It seems that when I remove the mousePressEvent function from the CustomItem class and change in the CustomView the mousePressEvent function to:
void CustomView::mousePressEvent(QMouseEvent *event){
cout << "pressing in view";
}
the CustomView handles all the mouseEvents.
How can I let the CustomItem handles the clicks in the items and the CustomView handle all the other clicks?
Thank you.
EDIT
So now I have changed it to:
class CustomView : public QGraphicsView
{
Q_OBJECT
public:
};
class CustomScene : public QGraphicsScene
{
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
};
void CustomScene::mousePressEvent(QGraphicsSceneMouseEvent *event){
cout << "pressing in scene";
}
class CustomItem : public QGraphicsItem
{
public:
CustomItem(CustomView* widget)
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
};
CustomItem::CustomItem(CustomView* widget){
setFlag(ItemIsSelectable);
setFlag(ItemIsMovable);
}
void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event){
cout << "pressing in item";
}
A Click in the scene but not in an item get handled by the scene. But clicks in the items
dont get handled by the items itself, instead it get handled by the scene. Unless if you click 2 times really fast on the items it gets handled by the scene and the item.
Any ideas?
QGraphicsView isn't really a good place to handle scene-specific events. Instead, you'll need to override QGraphicsScene::mousePressEvent. I would recommend something like this:
void CustomScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (itemAt(event) == NULL)
{
// do stuff if not clicked on an item
}
else
{
QGraphicsScene::mousePressEvent(event); // this forwards the event to the item
}
}
Note that QGraphicsScene::itemAt might give you difficulties if you have items with the ItemIgnoresTransformations flag set to true. Look to the docs for QGraphicsScene::itemAt for how to resolve this.

Resources