How to add clicked signal and slot to custom button in qt - c++

I have a Box class that inherits from QPushButton. I want to have a onClick event on the button by using connect (SIGNAL and SLOT) and call a custom function onClick() declared in box.h
box.h
#ifndef BOX_H
#define BOX_H
#include <QPushButton>
class Box : public QPushButton {
public:
Box(const QString& text, QWidget* parent = nullptr);
void onClick();
};
#endif // BOX_H
//box.cpp
#include "box.h"
Box::Box(const QString& text, QWidget* parent)
: QPushButton(text, parent)
{
connect(this, SIGNAL(clicked()), SLOT(this->onClick()));
}
void Box::onClick()
{
this->setText("Something");
}

your box needs the label for defining slots
class Box : public QPushButton
{
Q_OBJECT
public:
Box(const QString& text, QWidget* parent = nullptr);
//may be public or private
public slots:
void onClick();
};

Related

use a signal between 2 classes Qt

I have a MainWindow class which contain a QComboBox and a widget which is from another class. This second class contain a QCheckBox and a QComboBox. I want to use a signal to change the checkState of my QCheckBox and the string displayed in my QComboBox from my widget class when the string displayed in my QComboBox from my MainWindow has changed.
But I don't really understand which form my signal must have and how I can use it in my widget class.
MainWindow.h :
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
#include <QComboBox>
#include "devices_left_widget.h"
#define STRING_DEVICE1 "DEVICE1"
#define STRING_DEFAULT ""
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget* parent = nullptr);
signals:
public slots:
void carte_OK();
protected:
QComboBox* carte_type_combo_box;
devices_left_widget* left_widget;
};
#endif // MAINWINDOW_H
device_left_widget.h :
#ifndef DEVICE_LEFT_WIDGET_H
#define DEVICE_LEFT_WIDGET_H
#include <QWidget>
#include <QCheckBox>
#include <QComboBox>
#define STRING_DEVICE1 "DEVICE1"
#define STRING_DEFAULT ""
class device_left_widget : public QWidget {
Q_OBJECT
public:
explicit device_left_widget(QWidget* parent = nullptr);
signals:
public slots:
protected:
QGridLayout* main_grid_layout;
QCheckBox* device_checkbox;
QComboBox* device_type_combo_box;
};
#endif // DEVICES_LEFT_WIDGET_H
Let's call your widget's name container. We want to connect QComboBox's currentTextChanged(const QString &text) signal to the widget, so we create a slot that corresponds to the signal, let it be chosenTextChanged(const QString& text). We connect them inside MainWindow constructor:
connect(ui->comboBox, SIGNAL(currentTextChanged(const QString &)),
ui->container, SLOT(chosenTextChanged(const QString &)));
And inside your container class, define the slot as public:
public slots:
void chosenTextChanged(const QString &text) {
//change your QCheckBox's state and
//change your QComboBox's text
}

QComboBox with click to lineEdit

I wish derived class from QComboBox with following additional feature:
When user clicks to QLiineEdit of this combo box, the effect have to be the same as click to arrow on the right side of combo box (showPopup() method).
My attemption is:
File lineedit.h
#ifndef LINEEDIT_H
#define LINEEDIT_H
#include <QLineEdit>
class LineEdit : public QLineEdit {
Q_OBJECT
public:
LineEdit(QWidget *parent = nullptr);
signals:
void pressed();
protected:
void mousePressEvent(QMouseEvent *event) override;
};
#endif // LINEEDIT_H
File lineedit.cpp
#include "lineedit.h"
#include <QMouseEvent>
LineEdit::LineEdit(QWidget *parent) : QLineEdit(parent) {}
void LineEdit::mousePressEvent(QMouseEvent *event) {
QLineEdit::mousePressEvent(event);
emit pressed();
event->accept();
}
File combobox.h
#ifndef COMBOBOX_H
#define COMBOBOX_H
#include <QComboBox>
class ComboBox : public QComboBox {
Q_OBJECT
public:
ComboBox(QWidget *parent = nullptr);
private slots:
void lineEditPressed();
};
#endif // COMBOBOX_H
File combobox.cpp
#include "combobox.h"
#include "lineedit.h"
ComboBox::ComboBox(QWidget *parent) : QComboBox(parent) {
setLineEdit(new LineEdit);
connect(lineEdit(), SIGNAL(pressed()), this, SLOT(lineEditPressed()));
}
void ComboBox::lineEditPressed() { showPopup(); }
But, when I press lineEdit, it shows popup, but after releasing mouse button it vanishes.
Please, revise the documentation of the event handler. As you show pop-up menu in this function, then the release event will conflict hastily. I can't predict your implementation of showPopup(), but please don't create a pop-up menu inside it. You may show, hide, assign, but NEVER create.

cannot call button signal from abstract class

I want to call a function when a button click. the implementation of the button is in the abstract class. but when I compile I'm getting this error.
This is my .h file of the base class
#ifndef HOME_H
#define HOME_H
#include<QGraphicsScene>
#include <QGraphicsScene>
#include<QPushButton>
class home
{
Q_OBJECT
public:
home();
virtual void set_home_background()=0 ;
QGraphicsScene *scene3;
QPushButton *button3;
private slots:
virtual void startgame1();
};
#endif // HOME_H
This is the base class
#include "home.h"
#include<QGraphicsScene>
#include<QGraphicsProxyWidget>
#include "QMessageBox"
home::home()
{
}
void home::set_home_background()
{
button3 = new QPushButton;
QObject::connect(button3,SIGNAL(clicked()),this,SLOT(startgame1()));
QGraphicsProxyWidget *proxy = this->scene3->addWidget(button3);
button3->setAutoFillBackground(true);
button3->setIcon(QIcon(":/Images/ng.png"));
button3->setIconSize(QSize(131,41));
proxy->setPos(130,430);
scene3->addItem(proxy);
}
void home::startgame1()
{
QMessageBox q;
q.setText("");
q.exec();
}
I'm getting this error
C:\Users\User\Documents\breakout_final\home.cpp:16: error: no matching
function for call to 'QObject::connect(QPushButton*&, const char*,
home*, const char*)'
QObject::connect(button3,SIGNAL(clicked()),this,SLOT(startgame1()));
^
You have an error in your code: in order to use Qt signals and slots, you should inherit your class from QObject, Q_OBJECT declaration itself is not enough:
#include <QObject>
class home : public QObject
{
Q_OBJECT
public:
home();
virtual void set_home_background()=0 ;
QGraphicsScene *scene3;
QPushButton *button3;
private slots:
virtual void startgame1();
};

Subclassing QLabel and use it in QWidget class

When i try to put QLabel in QWidget class its not work properly (no hover event or click event only the label pixmap is show) only the last instance work properly, when not use set parent, it create in new window for each label but its work correctly
this gif show the problem:
https://media.giphy.com/media/3o7TKKmZSISGXN4Opq/giphy.gif
this is QLabel subclass header:
#include <QObject>
#include <QLabel>
class myLabel : public QLabel
{
Q_OBJECT
public:
myLabel();
protected:
void mousePressEvent(QMouseEvent *);
void enterEvent(QEvent *);
void leaveEvent(QEvent *);
signals :
void labelClicked();
void enterSignal();
void leaveEventSignal();
private:
};
this class to make a labelButton:
#include <QObject>
#include <QWidget>
#include "mylabel.h"
class labelButton : public QWidget
{
Q_OBJECT
public:
labelButton();
//some functions
private slots:
//slots
private:
//private member
};
and this the class that i want to use the labelButtons in:
#include <QWidget>
#include "labelbutton.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
labelButton *b_1, *b_2, *b_3;
};
here is widget.cpp:
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
b_1 = new labelButton;
b_1->setParent(this);
b_1->moveButton(70, 100);
//some functions to initialize the labelButton
b_1->show();
//-----------------------
b_2 = new labelButton;
b_2->setParent(this);
b_2->moveButton(70, 200);
//some functions to initialize the labelButton
b_2->show();
//-----------------------
b_3 = new labelButton;
b_3->setParent(this);
b_3->moveButton(70, 300);
//some functions to initialize the labelButton
b_3->show();
}
here its work, the problem was in passing the parent
i made a function that take a widget and set buttons parent from the function value
b_1 = new labelButton;
//b_1->setParent(this);
b_1->setParentFunc(this);
b_1->moveButton(70, 100);
//some functions to initialize the labelButton
// b_1->show();
in labelButton:
void labelButton::setParentFunc(QWidget *p)
{
myParent = p;
}
mLabel_1->setParent(myParent); // myParent instead of this

QGraphicsPixmapItem not selectable

I want my QGraphicsPixmapItem become selectable (i.e. clickable in more general way) on QGraphicScene but it doesn't. I'm actually modifying Qt's Diagram Scene sample, where QGraphicsItem's subclass is used and is selectable. I appreciate your help.
cpp code (partial):
#include <iostream>
#include <QtGui>
#include "overlayPixmapItem.h"
OverlayPixmapItem::OverlayPixmapItem(DiagramType diagramType, QMenu *contextMenu,
QPixmap img, QGraphicsItem *parent,
QGraphicsScene *scene)
: QGraphicsPixmapItem(img, parent), QObject()
{
myDiagramType = diagramType;
myContextMenu = contextMenu;
this->setAcceptsHoverEvents(true);
this->setAcceptHoverEvents(true); //
this->setAcceptedMouseButtons(Qt::LeftButton);
this->setAcceptedMouseButtons(Qt::RightButton);
this->acceptDrops();
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
}
:
header (partial):
#ifndef OVERLAYPIXMAPITEM_H
#define OVERLAYPIXMAPITEM_H
#include <QGraphicsPixmapItem>
#include <QList>
#include <QObject>
class QPixmap;
class QGraphicsItem;
class QGraphicsScene;
class QTextEdit;
class QGraphicsSceneMouseEvent;
class QMenu;
class QGraphicsSceneContextMenuEvent;
class QPainter;
class QStyleOptionGraphicsItem;
class QWidget;
class QPolygonF;
class OverlayPixmapItem : public QObject, public QGraphicsPixmapItem
{
Q_OBJECT
public:
enum { Type = UserType + 15 };
enum DiagramType { Crosshair };
OverlayPixmapItem(DiagramType diagramType, QMenu *contextMenu,
QPixmap img, QGraphicsItem *parent = 0, QGraphicsScene *scene = 0);
DiagramType diagramType() const { return myDiagramType; }
QPolygonF polygon() const { return myPolygon; }
int type() const { return Type;}
protected:
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
void hoverEnterEvent ( QGraphicsSceneHoverEvent * event );
void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event );
public: signals:
void mouseHoveredOnElem(OverlayPixmapItem *i);
void mouseHoveredOutOfElem(OverlayPixmapItem *i);
private:
DiagramType myDiagramType;
QPolygonF myPolygon;
QMenu *myContextMenu;
};
#endif // OVERLAYPIXMAPITEM_H
As pointed out in my first comment, you call setAcceptedMouseButtons() method twice. While the first call actually set the correct button to be accepted, the second call make this setting lost.
To accept both buttons on this item, you have to combine Qt MouseButtons flags, this way :
item->setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton) ;