Subclassing widgets in QT designer - c++

I am having a hard time subclassing Widgets in the QDesigner. I am using QDesigner to create my UI, but using cmake to compile rather than .pro files. So I am basically using QT Creator for nothing other than generating ui files.
Now I want to subclass QLabel in order to override the mouse click event, so as far as I understand all I have to do is right click the QLabel and select "promote to". It then asks me what i want to promote to, so I say "clickable_qlabel.h". However, when I call "make", I get "ui_mainWindow.h:95:5: error: ‘Clickable_QLabel’ does not name a type". Unfortunately I have no idea where I need to put clickable_qlabel.h, or whether it already exists and I just need to fill it with my code.
Any help would be greatly appreciated!
Many thanks.
[UPDATE]
OK, so now I have created the following class:
QLabelClickable.h
#ifndef _QLABELCLICKABLE_H_
#define _QLABELCLICKABLE_H_
#include <QLabel>
#include <QMouseEvent>
class QLabelClickable : public QLabel
{
Q_OBJECT
public:
explicit QLabelClickable( const QString& text="", QWidget* parent=0 );
~QLabelClickable();
signals:
void clicked(int, int);
protected:
void mousePressEvent(QMouseEvent* event);
};
#endif
QLabelClickable.cpp
#include "QLabelClickable.h"
QLabelClickable::QLabelClickable(const QString& text, QWidget* parent)
: QLabel(parent)
{
setText(text);
}
QLabelClickable::~QLabelClickable()
{
}
void QLabelClickable::mousePressEvent(QMouseEvent* event)
{
emit clicked(event->x(),event->y());
}
So this code compiles beautifully. So now I am in QtDesigner and I create a QLabel, called label4, and I right click and select "Promote to". Then under "Promoted class name:" I type "QLabelClickable" and under "Header file:" I type "QLabelClickable.h". Then I click "Promote". Wonderful. But I am still getting the error:
Vigil/build/ui_mainWindow.h:328:42: error: no matching function for call to ‘QLabelClickable::QLabelClickable(QWidget*&)’ label_4 = new QLabelClickable(tab);
So clearly QtDesigner needs to be instructed (somehow) where my implementation of QLabelClickable is. Quite frustrating.

Eh. My error, I should have read the error message properly. I hadn't included a constructor for the passing of only a QWidget. Adding
QLabelClickable::QLabelClickable( QWidget* parent ) : QLabel(parent) {
}
to my CPP has solved the problem! Hooray.

Related

Make Qlabel clickable or double clickable in Qt

I am beginner in Qt, now I want to make my label clickable, I have searched so much online, but no one gives my a real example of how they made it. So can someone teach me step by step? Now my basic thinking is creating a new .c file and new .h file respectively and then include them into my mainwindow.c and then connect it with the existing label in ui form. These are what I was trying to do, but can not make it. Hope someone can teach and better put the step picture in the command, thanks.
Here is the clicklabel.h code:
#ifndef CLICKEDLABEL_H
#define CLICKEDLABEL_H
#include <QWidget>
#include <QLabel>
class ClickedLabel : public QLabel
{
Q_OBJECT
public:
ClickedLabel(QWidget *parent=0): QLabel(parent){}
~ClickedLabel() {}
signals:
void clicked(ClickedLabel* click);
protected:
void mouseReleaseEvent(QMouseEvent*);
};
#endif // CLICKEDLABEL_H
This the clicklabel.c code:
#include "clicklabel.h"
void ClickedLabel::mouseReleaseEvent(QMouseEvent *)
{
emit clicked(this);
}
These are what I added into my mainwindow.c( the name of the label is click_test):
void data_labeling::on_label_clicked()
{
QString path="/home/j/Pictures/images.jpeg";
QPixmap cat(path);
connect(ui->click_test, SIGNAL(clicked()), this,
SLOT(on_label_clicked()));
ui->click_test->setPixmap(cat);
ui->click_test->resize(cat.width(),cat.height());
}
Of course I have promoted it to clicklabel.h and also I have added void on_label_click() to my mainwindow.h under private slots, but nothing happened.
Create a new class derived from QLabel, reimplement mousePressEvent to emit custom pressed() signal (or any other functionality you need)
If you need to use your clickable label in ui files, follow these steps:
Add QLabel to the form
Right-click on added label and select Promote to...
Enter your clickable label class name and its header file name
Press add, than select your label in the tree and select promote
Now you can use your subclassed label (this tutorial actually works for any subclassed widget) as any QWidget using ui->
You can use QPushButton instead, but if you desperately need QLabel, you can do this:
clickable.h
class Clickable :public QLabel
{
Q_OBJECT
signals:
void clicked();
public:
void mousePressEvent(QMouseEvent* event);
using QLabel::QLabel;
};
clickable.cpp
void Clickable::mousePressEvent(QMouseEvent* event)
{
emit clicked();
}
UPDATE:
This implementation I used in my source code. I can't paste complete code, but here is the part where I used it.
source.h
...
private:
QLabel* label1;
QLabel* label2;
...
source.cpp
...
label1 = new Clickable("label1 text", this);
label2 = new Clickable("label2 text", this);
...
connect(label1 , SIGNAL(clicked()), this, SLOT(label1clicked()));
connect(label2 , SIGNAL(clicked()), this, SLOT(label1clicked()));
...

How to easily get the button Press in a dialog box in Qt/C++

I have wrote an app which mainly is an equivalent to mac osx finder. When copying file into a folder, I'm checking if a file of the same name already exist. In case it exist, I'm asking the user if he want to cancel, overwrite or not overwrite.
The Dialog box for the overwrite has been created with QT designer and generate a dialogoverwrite.ui, .cpp and .h.
User Interface
dialogoverwrite.cpp
#include <QDialogButtonBox>
#include "dialogoverwrite.h"
#include "ui_dialogoverwrite.h"
DialogOverwrite::DialogOverwrite(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogOverwrite)
{
ui->setupUi(this);
}
DialogOverwrite::~DialogOverwrite()
{
delete ui;
}
dialogoverwrite.h
#include <QDialog>
#include <QDialogButtonBox>
namespace Ui {
class DialogOverwrite;
}
class DialogOverwrite : public QDialog
{
Q_OBJECT
public:
explicit DialogOverwrite(QWidget *parent = 0);
~DialogOverwrite();
private:
Ui::DialogOverwrite *ui;
};
I'm using this class in My TreeWidget application as shown below, I will only add the required code
DialogOverwrite *OverwriteDialog = new DialogOverwrite;
OverwriteDialog->exec();
A kind of OverwriteDialog.button.value could be perfect for me.
the exec will show the dialog and wait for a user action. How can I easily catch the return value : Cancel, Yes, YesToAll, No, NoToAll
I'm looking for an easy to get it. I would like to avoid any additional method in the dialogoverwrite class with signal/connecT. I really just need the button value to react.
Thanks a lot
Call QDialog::done(int r) with a value that represents one of the closing buttons. This value is returned by exec().
Default values are provided by QDialog::DialogCode enum.

Hiding/Showing DockWidgets in Qt 5 in Designer

I'm developing an application with Qt, a framework with which I'm not at all familiar, and I'm attempting to hide and show a DockWidget that I created using designer.
Unlike many of the seemingly similar questions about hiding and showing dockwidgets in Qt is that I made my widget entirely with Qt Designer, so I don't know how to link much of the code I've found in these questions' answers. Essentially, I have no mention of a dockwidget in my *.cpp files, but I do in my .ui file.
How can I incorporate this Designer-created dockwidget into my code to make it visible and invisible?
Sorry for such a nooby question.
Thanks,
erip
Wenn you build your application, qmake generates h from your ui files. So for instance ui_dlg_about.ui is translated into a ui_dlg_about.h automatically. Usually in a folder calles GeneratedFiles or something like that. You can then create an acutal customisable dialog class which you use in your application by creating something along the following:
dlg_about.h
#include "ui_dlg_about.h"
#include <QDialog>
class dlg_about : public QDialog, protected Ui::ui_dlg_about
{
Q_OBJECT
public:
dlg_about(QWidget* = 0);
public slots:
void toggle_dockwidget();
};
dlg_about.cpp
#include "dlg_about.h"
dlg_about::dlg_about(QWidget* parent) : QDialog(parent)
{
setupUi(this);
QObject::connect(this->somebutton, SIGNAL(clicked()), this, SLOT(toggle_dockwidget()));
}
void dlg_about::toggle_dockwidget()
{
if(something){
this->dockwidget->setVisible(true);
}else{
this->dockwidget->setVisible(false);
}
}
It is also possible for your dialog to not be derived from ui_dlg_about but having it as a member:
dlg_about.h
#include "ui_dlg_about.h"
#include <QDialog>
class dlg_about : public QDialog
{
Q_OBJECT
public:
dlg_about(QWidget* = 0);
public slots:
void toggle_dockwidget();
protected:
Ui::ui_dlg_about ui;
};
dlg_about.cpp
#include "dlg_about.h"
dlg_about::dlg_about(QWidget* parent) : QDialog(parent)
{
setupUi(this->ui);
QObject::connect(this->ui.somebutton, SIGNAL(clicked()), this, SLOT(toggle_dockwidget()));
}
....

qt4 designer add custom class

Hi i have made a gui in qt4 designer and want to add custom slots with custom class.
It project compiles nicely without errors but my custom function wont work what am i doing wrong? I will show u the header file qt4 designer made for me and ill show u my custom file as well as the main.cpp.. first the main.cpp
I have revised my code, here is what i have now i have added a file called sweetest.cpp and edited the sweetest.h here are my new file and the error i recieve..
First main.cpp
#include "ui_sweetguiform.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget *widget = new QWidget;
Ui::SweetGuiForm ui;
ui.setupUi(widget);
widget->show();
return app.exec();
}
now my custom header file sweetest.cpp
#include "sweetest.h"
// trying to include the .moc file wouldnt work at all.
now the sweettest.h file with my code
#include "ui_sweetguiform.h"
class SweetGuiForm : public QWidget
{
Q_OBJECT
public:
SweetGuiForm( ): ui( new Ui::SweetGuiForm )
{
ui->setupUi( this );
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(on_buttonBox_accepted()));
}
public slots:
void on_buttonBox_accepted()
{
ui.textEdit->setText(QString::number(23));
}
protected:
Ui::SweetGuiForm* ui;
};
Here is the compile error i recieve.. I am really stuck
In file included from sweetest.cpp:1:
sweetest.h: In member function ‘void SweetGuiForm::on_buttonBox_accepted()’:
sweetest.h:16: error: request for member ‘textEdit’ in ‘((SweetGuiForm*)this)->SweetGuiForm::ui’, which is of non-class type ‘Ui::SweetGuiForm*’
make: *** [sweetest.o] Error 1
I think im getting closer
The way that signals and slots work is that you must connect a signal to a slot. In your code, the simplest way to do that is in the constructor for the SweetGuiForm. You need to add:
SweetGuiForm() : ui(new Ui::SweetGuiForm) {
ui->setupUi(this);
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(on_buttonBox_accepted()));
}
When the buttonBox emits its accepted signal all slots connected to it will be called.
update 1
On further inspection of your code, you are also missing the Qt macros that are used by the Qt MOC (meta-object compiler) system (http://qt-project.org/doc/qt-4.8/moc.html):
class SweetGuiForm : public QWidget
{
Q_OBJECT
public:
...
};
You also have to push the code through the MOC tool. It will generate a source file that needs to be included in your source. As I recall, you must include that in a cpp file; inclusion in a header is problematic. The following should be sufficient:
sweetguiform.cpp:
#include "suiteguiform.h"
#include "sweetguiform.moc"
update 2
On further further reflection, I had forgotten about the automatic signal/slot connection feature when you name your slots using special names (such as on_buttonBox_accepted). There is a blog post on just that here: http://qtway.blogspot.com/2010/08/automatic-connections-using-qt-signals.html. I've not used it myself, so I can't comment on its ability to work when using a ui member variable, though I suspect that it does not work in that arrangement. Regardless, you still need the Q_OBJECT macro and MOC.
Ok guys i figured it out and thought ide share what i found.
First the documentation is excellent in qt4 use it.
I found you can use qt4 designer to generate the hearder files, first i complied it with out custom slots and generated the ui_sweetgui2.h, then i could open the sweetgui2.h file generated by the first compile i did delete what qt4 put in there and put my custom slots in at that stage. did my head in for hours.... days.
so here is the simplest app on earth but its got me started so here are the files and code that worked for me and the documentation basically got me to click on to whats going on.
main.cpp
Strait from the documentation just changed the class name "SweetGuiForm".
#include <QApplication>
#include "sweetgui2.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
SweetGuiForm sweetgui;
sweetgui.show();
return app.exec();
}
next sweetgui2.cpp
My first attempt at c++.. ugly but works. But again i found everything about getting the text from the textEdit and type casting it to a int in the calculator example and searching for toPlainText() in the qt4 assistant. notice below im including the file that i will define the new slots that ill show further on in my explanation. hope im making sense.
#include <QtGui>
#include "sweetgui2.h"
SweetGuiForm::SweetGuiForm(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
}
void SweetGuiForm::on_buttonBox_accepted()
{
QString stringamount = ui.textEdit->toPlainText();
int digitamount = stringamount.toInt();
ui.textEdit->setText(QString::number(25 + digitamount));
}
next sweetgui2.h the one we included above My custom header file with my custom slot.... simple as i said from the calculator example and twisted a lil.. you will get it this is not what it looks like when you generate it from designer on the first compile this is after i have deleted nearly all what was there and opened the calculator example and followed in the tutorial wich shows you how to make your first custom slot .
#ifndef SWEETGUI2_H
#define SWEETGUI2_H
#include "ui_sweetgui2.h"
class SweetGuiForm : public QWidget
{
Q_OBJECT
public:
SweetGuiForm(QWidget *parent = 0);
private slots:
void on_buttonBox_accepted();
private:
Ui::SweetGuiForm ui;
};
#endif // SWEETGUI2_H
Again Straight from the documentation. I used the calculator example to get the basic flow.
next ui_sweetgui2.h
I include this file because i was trying to add my slots to the sweetgui2.h that was generated by qt4 desinger. doesnt work guys ..so i compiled first with sweetgui2.h file you generate with the designer, i go to forms menu then view code that is where u can save header files. then of course save the ui file.
and compile then you end up with the ui_sweetgui2.h file wich looked like the sweetgui2.h generated by the designer
#ifndef UI_SWEETGUI2_H
#define UI_SWEETGUI2_H
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QDialogButtonBox>
#include <QtGui/QHeaderView>
#include <QtGui/QTextEdit>
#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
class Ui_SweetGuiForm
{
public:
QDialogButtonBox *buttonBox;
QTextEdit *textEdit;
void setupUi(QWidget *SweetGuiForm)
{
if (SweetGuiForm->objectName().isEmpty())
SweetGuiForm->setObjectName(QString::fromUtf8("SweetGuiForm"));
SweetGuiForm->resize(486, 238);
buttonBox = new QDialogButtonBox(SweetGuiForm);
buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setGeometry(QRect(150, 200, 181, 26));
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
textEdit = new QTextEdit(SweetGuiForm);
textEdit->setObjectName(QString::fromUtf8("textEdit"));
textEdit->setGeometry(QRect(150, 50, 221, 91));
retranslateUi(SweetGuiForm);
QObject::connect(buttonBox, SIGNAL(rejected()), SweetGuiForm, SLOT(close()));
QMetaObject::connectSlotsByName(SweetGuiForm);
} // setupUi
void retranslateUi(QWidget *SweetGuiForm)
{
SweetGuiForm->setWindowTitle(QApplication::translate("SweetGuiForm", "SweetGuiBack", 0, QApplication::UnicodeUTF8));
} // retranslateUi
};
namespace Ui {
class SweetGuiForm: public Ui_SweetGuiForm {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_SWEETGUI2_H
Then i recompiled again with my custom slots and shazam! now i can begin to learn some c++.
thanks for all the hints guys, between you all and the documentation i got there.
hope this helps. The main thing to look at is the order things are included i mean my sweetgui2.cpp file
includes the sweetgui2.h file. wich grabs all my custom stuff.
My sweetgui2.h file
includes the ui_sweetgui2.h wich has all the stuff the designer made when i did the first compile. Main.cpp calls my SweetGuiForm class .
As you all can see my first couple days with c++ but this is a good starting point. it made me put the basic flow together in my mind. qt4 assistant look at it.. its well explained and the examples seem very good. ho ho ho merry xmas. hope my explanation helps.

Subclass of QEditLine with a new SIGNAL

I am trying to subclass QEditLine so that I can define a new SIGNAL that sends an object identifier. At the moment, I connect a parent signal to a slot in the new class and from that slot I emits a proper new signal with the additional object identifier.
I cannot understand one thing. The problem is I don't know how to define a new signal function itself. I don't know what I should put there. I mean I know its arguments but I don't know what it shpould do as a function. I am doing this for the first time and it may looks very silly ;p but I really stuck there >.<.
Can anybody please provide some clues. It is probably a very easy problem.
Thanks
// myqeditline.h
#ifndef MYQEDITLINE_H
#define MYQEDITLINE_H
#include <QWidget>
#include <QLineEdit>
#include <QString>
class MyQEditLine : public QLineEdit
{
Q_OBJECT
public:
explicit MyQEditLine(const QString& n, QWidget *parent = 0);
protected:
QString name;
signals:
void textChanged(QString textCHanged, QString sender);
protected slots:
public slots:
void myTextChanged(QString textChanged);
};
#endif // MYQEDITLINE_H
// myqeditline.cpp
#include "myqeditline.h"
MyQEditLine::MyQEditLine(const QString &n, QWidget *parent)
: QLineEdit(parent),name(n) {
connect(this,SIGNAL(textChanged(QString)),this,SLOT(myTextChanged(QString)));
}
void MyQEditLine::myTextChanged(QString textChanged) {
emit textChanged(QString textChanged, QString name);
}
I just realised that the answer to my question is on this Qt Project website, in section regarding "Signals", in 4th paragraph. It says: "Signals are automatically generated by the moc and must not be implemented in the .cpp file. They can never have return types (i.e. use void)."