I have a problem regarding my QT project. I want to create a touchable Qlabel, so I created a placeholder in the gui designer and referenced it to my "watchlistlabel" which extends from QLabel. When I now start my app I get the error " no matching function for call to WatchListLabel::WatchListLabel(QGroupBox*&)'
name1 = new WatchListLabel(groupBox_3);
My labels are in a groupbox does this affect my code?
why it cant find a matching function?
^
#include<QLabel>
class WatchListLabel: public QLabel
{
Q_OBJECT
private:
void mousePressEvent(QMouseEvent * event) override;
public:
WatchListLabel();
};
watchlistlabel.cpp
#include "watchlistlabel.h"
void WatchListLabel::mousePressEvent(QMouseEvent *event)
{
}
WatchListLabel::WatchListLabel()
{
}
QTdesigner
You are missing a constructor which takes parent widget. General advice against this is to create new QObject subclasses using Qt Creator new class wizard, it will get everything right. But to solve the problem with this class, try replacing your default constructor with this constructor:
Declaration in .h:
explicit WatchListLabel(QWidget *parent = nullptr);
Definition in .cpp:
WatchListLabel::WatchListLabel(QWidget *parent)
: QLabel(parent)
//, any other member variable initializations
{
// any constructor code if needed
}
Related
We are developing in C++ (and Qt) using Visual Studio 2015 and the Qt Designer for our UI (via Form / .ui files).
We now need to share some Common Data between our UI elements (e.g. most recently used paths etc.) and I would like to do this via dependency injection (i.e. providing the UI with a Reference to the common object during construction) instead of e.g. (ab)using the singleton pattern.
Has someone faced (and solved) similar problems, and is there a sensible way to do this?
Update (to elaborate):
For example I have a custom FooWidget which I wish to use in my FooDialog.ui form file.
// My custom Widget
class FooWidget : public QWidget {
Q_OBJECT
public:
FooWidget(QWidget* parent);
//...
}
// The FooDialog class (scaffolding created by Qt Designer)
class FooDialog : public QDialog {
Q_OBJECT
public:
FooDialog(QWidget* parent) : QDialog(parent), ui (new Ui::FooDialog()) {
ui->setupUp(this);
//...
}
private:
Ui::FooDialog* ui;
}
// The Ui::FooDialog class autogenerated(!) by Qt Designer
// I cannot (must not) change this code, as it will be regenerated every time
class Ui_FooDialog {
public:
FooWidget* widget;
void setupUi(QWidget *fooDialog) {
//...
widget = new FooWidget(fooDialog);
//...
}
}
namespace Ui { class ScannerStatus: public Ui_ScannerStatus {}; }
I would like to provide the FooWidget with a common data object (e.g. text size and colours shared across all my Ui classes), but I can't do so in the constructor (since the autogenerated Ui_FooDialog treats FooWidget as a generic QWidget, which only needs/takes a QWidget* parent in the constructor - I cannot provide a pointer or reference to my shared TextColourAndSize object.
I am aware I could create a second ui->widget->setupTextColourAndSize(...) step in FooDialog (after the initial ui->setupUi(this)) which provides that common data object, but having two init() type functions seems like a rather bad code smell (one is bad enough).
FooWidget needs two constructors, and a setter for the dependency:
explicit FooWidget(QObject *parent = nullptr) : QWidget(parent), … {
…
}
FooWidget(Dependency *dep, QObject *parent = nullptr) : FooWidget(parent) {
setDependency(dep);
}
void setDependency(Dependency *dep) {
…
}
Then you’d set the dependency after the widget is constructed:
FooDialog(Dependency *dep, …) … {
setupUi(this);
ui->fooWidget->setDependency(dep);
}
This could be automated: the parent widget can have a property that holds the pointer to the dependency, and the child widgets can find it automatically:
FooDialog(Dependency *, …) : … {
setProperty("dependency", dep);
setupUi(this);
}
FooWidget(QWidget *parent) : … {
auto *dep = parent() ? parent()->property("dependency").value<Dependency*>() : nullptr;
if (dep) setDependency(dep);
}
This will work with no extra effort if Dependency derives from QObject. Otherwise, you’ll need to have the following in a suitable header file:
class Dependency { … };
Q_DECLARE_METATYPE(Dependency*)
In all circumstances, you do need to promote the fooWidget object to FooWidget class within Qt Designer.
Ok from what I'm seeing you do not need "dependency injection". Question was incorrectly stated.
You can use this custom widget directly from Qt designer.
When you create your FooDialog place regular widget QWidget in place where you need to have a FooWidget.
Then "promote" regular this widget to FooWidget (possibly you have to add some simple information about that type) - (I did that long time ago and do not remember all details).
For detailed instruction just google: qt promote widget qt designer, you will find lots of examples how to do it.
These were good solutions, but talking about dependency injections, there is also an option to have some fun with C++. It's not a wise solution at all, of course I know it, but nevertheless...
foowidget.h
#ifndef FOOWIDGET_H
#define FOOWIDGET_H
#include <QWidget>
class Something
{
public:
QString getHello() const
{ return "Hello world!"; }
};
/***************************************************/
template<typename T>
class Injector
{
public:
QString getHello() const
{ return m_dataContainer.getHello(); }
private:
T m_dataContainer;
};
/***************************************************/
class FooWidget : public QWidget, public Injector<Something>
{
Q_OBJECT
public:
explicit FooWidget(QWidget* parent = nullptr);
protected:
virtual void mousePressEvent(QMouseEvent*) override;
};
#endif // FOOWIDGET_H
foowidget.cpp
#include "foowidget.h"
#include <QMessageBox>
FooWidget::FooWidget(QWidget *parent)
: QWidget(parent)
{ }
void FooWidget::mousePressEvent(QMouseEvent*)
{
QMessageBox::information(nullptr, "Test", getHello());
}
foodialog.h
#ifndef FOODIALOG_H
#define FOODIALOG_H
#include <QDialog>
class SomethingElse
{
public:
QString getHello() const
{ return "OMG! OMG"; }
};
#include "foowidget.h"
namespace Ui {
class FooDialog;
}
class FooDialog : public QDialog, public Injector<SomethingElse>
{
Q_OBJECT
public:
explicit FooDialog(QWidget *parent = nullptr);
~FooDialog();
protected:
void showEvent(QShowEvent *) override;
private:
QScopedPointer<Ui::FooDialog> ui;
};
#endif // FOODIALOG_H
foodialog.cpp
#include "foodialog.h"
#include "ui_foodialog.h"
#include <QMessageBox>
FooDialog::FooDialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::FooDialog)
{
ui->setupUi(this);
}
FooDialog::~FooDialog()
{ }
void FooDialog::showEvent(QShowEvent *)
{
QMessageBox::information(nullptr, "Test", getHello());
}
Multiple inheritance + deriving widgets from some small template proxy class works for both custom widgets and those, having UI forms. I've put a FooWidget on a FooDialog (via propagation mechanizm) in the sketch above and got two message boxes.
The idea itself can be implemented better, with smarter template usage, just tried to reduce sample code, anyway it's an unnessesary complication. But technically it works without any additional initializations =)
I just want to make a custom Dialog, so I want to make a class around the standard QDialog. The goal is to call the constructor which creates the Dialog, and the show() function should be called to make it shown. Next step would be to make a connect between my Widget (which calls the Dialog constructor) Pushbutton and the show() function.
My header looks like this:
#include <QDialog>
class Dialog_Setting : public QDialog
{
Q_OBJECT
public:
Dialog_Setting();
public slots:
void show(void);
private:
QDialog * dialog;
};
my .cpp:
#include "Dialog_Setting.h"
Dialog_Setting::Dialog_Setting()
{
dialog = new QDialog;
}
void Dialog_Setting::show()
{
dialog->show();
}
I have taken out my connect and get a new error.
What is wrong with my class?
undefined reference to `vtable for Dialog_Setting'
thanks for your help, I love StackOverflow
Make sure that show() is implemented as a slot so you can connect() stuff to it:
#include <QDialog>
class Dialog_Setting : public QDialog
{
Q_OBJECT
public:
Dialog_Setting();
public slots:
void show();
};
You also forgot to inherit from QObject or some other QObject-based class like QDialog and to declare the macro Q_OBJECT. All of these things are required to make your custom classes communicate with other classes through connect().
I have a Qt GUI called MainWindow.
I am rendering some 3D objects in the constructor of the MainWindow.
Moreover I declared a custom class of the vtkInteractorStyleTrackballCamera in MainWindow.cpp like in this example.
Now I would like to call a function from the MainWindow class in the function OnLeftButtonDown() from my custom class of the Interactor.
I tried to inherit the MainWindow class to the custom Interactor class like this:
class customMouseInteractorStyle : public vtkInteractorStyleTrackballCamera, MainWindow
But this doesn't work.
How can I access the functions of the MainWindow there?
The function is automatically called when pressing the left button of the mouse.
// Define interaction style
class customMouseInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
static customMouseInteractorStyle* New();
vtkTypeMacro(customMouseInteractorStyle, vtkInteractorStyleTrackballCamera);
virtual void OnRightButtonDown()
{
MainWindowfunction(); // <- I want to call this
vtkInteractorStyleTrackballCamera::OnRightButtonDown();
}
};
vtkStandardNewMacro(customMouseInteractorStyle);
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
// Rendering some things
}
void MainWindow::MainWindowfunction
{
// Do something
}
To answer your specific question, so you say you have this constructor:
customMouseInteractorStyle(MainWindow *ptr) { ptr->MainWindowfunction(); }
To make this work, first add a member variable:
private:
MainWindow *mainWin;
Then change the constructor to initialize it:
customMouseInteractorStyle(MainWindow *ptr) : mainWin(ptr) {}
Then your OnRightButtonDown becomes:
virtual void OnRightButtonDown()
{
mainWin->MainWindowfunction();
vtkInteractorStyleTrackballCamera::OnRightButtonDown();
}
I'm a Qt newbie and all I'm trying to do is create a custom QLineEdit class with a few customizations (default alignment and default text). Right now I'm just trying to establish a base class, inheriting only QWidget. This is what I have (very bad code I know):
userText (utxt.h):
#ifndef UTXT_H
#define UTXT_H
#include <QWidget>
#include <QLineEdit>
class utxt : public QWidget
{
Q_OBJECT
public:
explicit utxt(QWidget *parent = 0);
QString text () const;
const QString displayText;
Qt::Alignment alignment;
void setAlignment(Qt::Alignment);
signals:
public slots:
};
#endif // UTXT_H
utxt.cpp:
#include "utxt.h"
utxt::utxt(QWidget *parent) :
QWidget(parent)
{
QString utxt::text()
{
return this->displayText;
}
void utxt::setAlignment(Qt::Alignment align)
{
this->alignment = align;
}
}
I know this is really wrong, and I keep getting "local function definition is illegal" errors on the two functions in utxt.cpp. Can someone please point me in the right direction? I'm just trying to create a custom QLineEdit to promote my other line edits to.
QLineEdit already has the alignment that can be set and also placeholderText.
LE: As I said there is no need to inherit from QLineEdit (or QWidget) for this functionality, but if you really want to do it you can just create your class and code a constructor that takes the parameters you want and call QLineEdit's functionality with that, something like:
//in the header
//... i skipped the include guards and headers
class utxt : public QLineEdit
{
Q_OBJECT
public:
//you can provide default values for all the parameters or hard code it into the calls made from the constructor's definition
utxt(const QString& defaultText = "test text", Qt::Alignment align = Qt::AlignRight, QWidget *parent = 0);
};
//in the cpp
utxt::utxt(const QString& defaultText, Qt::Alignment alignement, QWidget *parent) : QLineEdit(parent)
{
//call setPlaceHolder with a parameter or hard-code the default
setPlaceholderText(defaultText);
//same with the default alignement
setAlignment(alignement);
}
I have seen many examples on how to use a paintevent, but I just cannot get it to work.
I have in my .ui file a label named 'image' and I am trying to paint inside it. I fail miserably. In most of the examples I've seen they use the
QLabel::paintEvent(e)
but I cannot use this, I get:
error: cannot call member function 'virtual void QLabel::paintEvent(QPaintEvent*)' without object
And, when I use
ui->image->paintEvent(e);
I get
/usr/include/qt4/QtGui/qlabel.h:141: error: 'virtual void QLabel::paintEvent(QPaintEvent*)' is protected
I seem to be missing something... That's the part of my code that I try to implement this:
void crop_my_image::paintEvent(QPaintEvent *e)
{
ui->image->paintEvent(e);
QPainter painter(ui->image);
painter.setPen(QPen(QBrush(QColor(0,0,0,180)),1,Qt::DashLine));
painter.setBrush(QBrush(QColor(255,255,255,120)));
painter.drawRect(selectionRect);
}
crop_my_image is of QDialog type!
PS: If, instead of ui->image->paintEvent(e); I use QDialog::paintEvent(e); I can successfully draw on my dialog, so I should be in the right path!
Thanks in advance for any answers!
You have to do exactly the same with label what you did with QDialog, which is create class which will inherit from QLabel and implement paintEvent function. Example:
//MyLabel.h
class MyLabel : public QLabel
{
Q_OBJECT
public:
MyLabel(QWidget *parent = 0);
private:
void paintEvent(QPaintEvent *);
};
//MyLabel.cpp
MyLabel::MyLabel(QWidget *parent)
: QLabel(parent)
{
/*...*/
}
void MyLabel::paintEvent(QPaintEvent *)
{
/* paint somehting on your label*/
}
And than you will be able to do:
void crop_my_image::paintEvent(QPaintEvent *e)
{
myLabelObject->paintEvent(e);
QPainter painter(ui->image);
painter.setPen(QPen(QBrush(QColor(0,0,0,180)),1,Qt::DashLine));
painter.setBrush(QBrush(QColor(255,255,255,120)));
painter.drawRect(selectionRect);
}
But firstly, why event you want to invoke this method?