Qt, using OpenGL, QGLWidget is private - c++

I'm quite new to Qt. I wanted to create a simple application where there's triangle generated using OpenGL and three push buttons changing that triangle colour. Unfortunately I get an error:
E:\Programy\Qt\5.3\mingw482_32\include\QtOpenGL\qgl.h:457: error: 'QGLWidget::QGLWidget(const QGLWidget&)' is private
Q_DISABLE_COPY(QGLWidget)
I don't know what to do. Here's my code:
MainWindow.h
class MainWindow : public QMainWindow
{
Q_OBJECT
QVBoxLayout *layout;
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
QPushButton *redButton;
QPushButton *greenButton;
QPushButton *blueButton;
public slots:
void redSlot(Widget w);
void greenSlot(Widget w);
void blueSlot(Widget w);
};
Slots in MainWindow.cpp look like this:
void MainWindow::redSlot(Widget w)
{
w.setColor(red);
}
Widget.h
class Widget : public QGLWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
QSize minimumSizeHint() const;
QSize sizeHint() const;
enum color c;
void setColor(enum color color1);
protected:
void initializeGL();
void paintGL();
void resizeGL(int width, int height);
};
enum color is just an enum declared ina another header file
enum color
{
red,
green,
blue
};

Your Slots
void redSlot(Widget w);
void greenSlot(Widget w);
void blueSlot(Widget w);
all take a Parameter of Type Widget. This tries to create a copy of the object when called. Your Widget is a subclass of QGLWidget which has a private copy constructor and therefore can't be called from a subclassed object.
As you want to change the color of an existing object and not a copy of it you should change the functions to take a pointer of that object:
void redSlot(Widget*);
void greenSlot(Widget*);
void blueSlot(Widget*);
void MainWindow::redSlot(Widget* w)
{
w->setColor(red);
}

Related

QT extend MainWindow to other class or diffrent way

I have class printrectangle
class PrintRectangle : public QWidget
{
Q_OBJECT
public:
explicit PrintRectangle(QWidget *parent = 0);
private:
void resetClickedIndex();
void updateIndexFromPoint( const QPoint& point);
public:
int mXIndex;
int mYIndex;
QVector<QPoint> points;
bool clicked[5][5] = {};
teacher tech;
perceptron p[5][5];
double techconst = 0.1;
signals:
public slots:
protected:
void paintEvent(QPaintEvent *);
void mousePressEvent(QMouseEvent *eventPress);
};
and MainWindow
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_learn_clicked();
void on_classify_clicked();
private:
Ui::MainWindow *ui;
};
When I click button I call to on_learn_clicked() function. I would like to transfer clicked[5][5] array into on_learn_clicked becasue I send this array to other object when user click button. How to do this?
It is not clear what is exactly the relation between MainWindow and the PrintRectangle widget. I suppose the button signal and PrintRectangle slot are connected somewhere in the MainWindow implementation.
One way to solve the problem would be to use to use the QSignalMapper as #Noidea stated.
Another way would be to use a lambda as a slot when connecting. This way you could capture the sender/receiver or other objects in scope and use their members.
You can find some information about the connect syntax in New Signal Slot Syntax
But basically you could write something like:
connect(button, &QPushButton::clicked, this, [this, printRectangle]()
{
// do smth with clicked[5][5] from printRectangle or just
// retrieve it and call another method like:
// this->processClicked(printRectangle->clicked);
// or pass it to another object
}
This way you could modify your on_classify_clicked slot to a regular method with bool[5][5] argument to do the processing.

Qt slot, no matching function for call

I'm quite new to Qt. I wanted to create a simple application where there's triangle generated using OpenGL and three push buttons changing that triangle colour.
Here's my code:
In MainWindow.h I declare slots:
public slots:
void redButton(Widget w);
void greenButton(Widget w);
void blueButton(Widget w);
They change colour using function in Widget class:
void MainWindow::redButton(Widget w)
{
w.setColor(red);
}
In widget.h I have:
class Widget : public QGLWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
QSize minimumSizeHint() const;
QSize sizeHint() const;
enum color
{
red,
green,
blue
};
enum color c;
void setColor(enum color color1);
protected:
void initializeGL();
void paintGL();
void resizeGL(int width, int height);
};
And function setColor looks like this:
void Widget::setColor(enum color color1)
{
c = color1;
}
Unfortunately I get an error saying:
no matching function forr call to 'Widget::setColor(QPushButton*&)'
w.setColor(red);
//Same goes for blue and green
I don't know what I'm doing wrong.
Well, your function declaration
void Widget::setColor(enum color color1);
obviously doesn't match your calls for
void Widget::setColor(QPushButton*&);
Certainly none of those QPushButton instances, establishes a valid instance of enum color, thus you get those compiler errors.

Qt, OpenGL Widget, no such slot

I wanted to create a simple application where there's triangle generated using OpenGL and three push buttons changing that triangle color. The triangle is generated but unfortunately buttons don't work and I get errors saying:
QObject::connect: No such slot MainWindow::redSlot(OGL) in
..\buttonwidget\mainwindow.cpp:17 QObject::connect: No such slot
MainWindow::greenSlot(OGL) in ..\buttonwidget\mainwindow.cpp:20
QObject::connect: No such slot MainWindow::blueSlot(OGL) in
..\buttonwidget\mainwindow.cpp:23
I have slots definitions:
void MainWindow::redSlot(Widget* w)
{
w->setColor(red);
}
void MainWindow::greenSlot(Widget* w)
{
w->setColor(green);
}
void MainWindow::blueSlot(Widget* w)
{
w->setColor(blue);
}
They are changing variable declared in class Widget that changes color of a generated triangle. Here's class Widget:
class Widget : public QGLWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
QSize minimumSizeHint() const;
QSize sizeHint() const;
enum color c;
void setColor(enum color color1);
protected:
void initializeGL();
void paintGL();
void resizeGL(int width, int height);
};
And then I connect slots to buttons in class MainWindow constructor:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
layout = new QVBoxLayout();
QWidget *w = new QWidget();
setCentralWidget(w);
w->setLayout(layout);
Widget *OGL = new Widget();
//OGL->c=green; - it was a test whether changing value of enum type variable c works
//it works, changing it changes the color of a generated triangle
redButton = new QPushButton(tr("Red"));
connect(redButton, SIGNAL(clicked()), this, SLOT(redSlot(OGL)));
greenButton = new QPushButton(tr("Green"));
connect(greenButton, SIGNAL(clicked()), this, SLOT(greenSlot(OGL)));
blueButton = new QPushButton(tr("Blue"));
connect(blueButton, SIGNAL(clicked()), this, SLOT(blueSlot(OGL)));
layout->addWidget(OGL);
layout->addWidget(redButton);
layout->addWidget(greenButton);
layout->addWidget(blueButton);
}
Here's slot declaration in header:
class MainWindow : public QMainWindow
{
Q_OBJECT
QVBoxLayout *layout;
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
QPushButton *redButton;
QPushButton *greenButton;
QPushButton *blueButton;
public slots:
void redSlot(Widget*);
void greenSlot(Widget*);
void blueSlot(Widget*);
};
How should I make them work?
Connects in QT are string-based, that means:
connect(redButton, SIGNAL(clicked()), this, SLOT(redSlot(OGL)));
will not work, since you havent defined a slot "redSlot(OGL)", instead you would have to use
...SLOT(redSlot(Widget*)));
Moreover, it is possible to define a SLOT with less parameter but not with more, therefore your slot/connect has to look like
void redSlot();
connect(redButton, SIGNAL(clicked()), this, SLOT(redSlot()));
if you need a pointer to the "Widget" you have to retrieve it from somewhere else.
Example: Define slot in "Widget"-class and change connect to:
connect(redButton, SIGNAL(clicked()), OGL, SLOT(redSlot()));

Qt connect itemDoubleClicked to self-defined slot

I have the following class that extends QListWidget, but I can't seem to connect the doubleClicked signal to the slot I desire. Here's the code implemented - in VS2012. The idea is to be able to double click a item and edit it. I connect the signal to the slot in the constructor, but the slot is never called when I run it through the debugger.
# .h file
class DisplayFeed :
public QListWidget
{
Q_OBJECT
public:
DisplayFeed(QWidget *parent, Logic *logic, int xpos, int ypos, int width, int height, std::string color);
~DisplayFeed(void);
void setColor(std::string color);
void refresh(std::vector<Event*> *thingsToInclude);
private:
Logic* logic;
private slots:
void editItem(QEventStore *item);
};
Below is the .cpp file. QEventStore extends QListWidgetItem. I placed the MessageBox to test the system as well, in case it was my other code that didn't work.
# .cpp file, only relevant methods included
DisplayFeed::DisplayFeed(QWidget *parent, Logic *logic, int xpos, int ypos, int width, int height, std::string color)
: QListWidget(parent)
{
this->logic = logic;
setGeometry(xpos, ypos, width, height);
setColor(color);
QObject::connect(this, SIGNAL(itemClicked(QEventStore*)), this, SLOT(editItem(QEventStore*)));
show();
}
void DisplayFeed::editItem(QEventStore *item){
QMessageBox::information(this,"Hello!","You clicked \""+item->text()+"\"");
QEventEditor *editor = new QEventEditor(item->getEvent());
}
You forgot the Q_OBJECT macro in your DisplayFeed class. It should be like :
# .h file
class DisplayFeed :
public QListWidget
{
Q_OBJECT
public:
DisplayFeed(QWidget *parent, Logic *logic, int xpos, int ypos, int width, int height, std::string color);
~DisplayFeed(void);
void setColor(std::string color);
void refresh(std::vector<Event*> *thingsToInclude);
private:
Logic* logic;
private slots:
void editItem(QEventStore *item);
};
That's the first thing I noticed and may solve your problem. If not I'll look deeper.
EDIT: Read the first answer here
There are several changes to do:
Add Q_OBJECT in the .h of displayFeed class
class DisplayFeed : public QListWidget
{
Q_OBJECT
...
};
Change your slot with a public slot and a QListWidgetItem* parameter
public slots:
void editItem(QListWidgetItem *item);
Connect with the good SIGNAL which have the same parameter that your SLOT
connect(this,SIGNAL(itemDoubleClicked(QListWidgetItem*)), this,SLOT(editItem(QListWidgetItem*)));
This works fine for me, hope it helps you.
I have found the answer. The problem is that the default signal for itemDoubleClicked emits the QListWidgetItem* and emitting a subclass of that doesn't work. So what I had to do was to go to editItem and get it to dynamic_cast the QListWidgetItem* to a QEventStore*

Adding a child widget to another widget in Qt

Although there are similar questions to mine posted on stackoverflow, none of their solutions actually respond to my problem. I have 2 independent widgets that I would like to combine (insert one widget into the other as a child): one is a UI created only with Qt Creator (drag-and-drop), and the other one an animation done in Qt with OpenGL. I am trying to add the animation in the UI and here is the code:
glwidget.h (animation):
class GLWidget : public QGLWidget
{
public:
GLWidget(QWidget *parent);
~GLWidget();
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
void drawCube(int i, GLfloat z, GLfloat ri, GLfloat jmp, GLfloat amp);
QGLFramebufferObject *fbo;
};
and glwidget.cpp:
GLWidget::GLWidget(QWidget *parent)
: QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{
makeCurrent();
fbo = new QGLFramebufferObject(512, 512);
timerId = startTimer(20);
}
GLWidget::~GLWidget()
{
glDeleteLists(pbufferList, 1);
delete fbo;
}
void GLWidget::initializeGL()
{....
As for the UI, I have the header file:
class ClaraTeCourseSimulator : public QMainWindow
{
Q_OBJECT
public:
explicit ClaraTeCourseSimulator(QWidget *parent = 0);
~ClaraTeCourseSimulator();
private:
Ui::ClaraTeCourseSimulator *ui;
GLWidget *defaultAnim;
protected:
void setupActions();
protected slots:
void addAnimWidget();
};
and the .cpp file:
ClaraTeCourseSimulator::ClaraTeCourseSimulator(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::ClaraTeCourseSimulator)
{
ui->setupUi(this);
defaultAnim = new GLWidget(ui->centralWidget);
}
void ClaraTeCourseSimulator::setupActions()
{
connect(ui->actionCar_Modelling, SIGNAL(triggered(bool)), ui->centralWidget,
SLOT(addAnimWidget()));
}
void ClaraTeCourseSimulator::addAnimWidget()
{
ui->centralWidget->layout()->addWidget(defaultAnim);
}
ClaraTeCourseSimulator::~ClaraTeCourseSimulator()
{
delete ui;
}
But when I try to run it I get about 24 of these errors: undefined reference to `imp_ZN9QGLFormatD1Ev all pointing to the constructor and destructor in glwidget.cpp.
What am I doing wrong? How can I fix this problem?
Are you trying to change the central widget to the GL one? Because specifying the parent for the GL widget does not change them. If you'd like to change a widget to another (using the Designer), I recommend the "promote to" feature, with which you can change a widget's actual class in the designer. So add a QWidget on the UI, and than promote it to your class (GLWidget).
It seems like the problem is with the GLFormat constructor call in the GLWidget constructor.