This is the second way I have rearranged this, and it is doing the same thing, so now I seek help. There are no errors being thrown, the slot just never does anything.
There are two other connections that are working between the same two cpps, and I decided to add this third one that the main window triggers, to the main window.
on_line_edit_returnPressed(), is printing hol_num and that is where it ends. ReadyHollander emits and HolPub never does anything. What am I doing wrong?
mainwindow cpp
#include "wheelscannerui.h"
#include "./ui_wheelscannerui.h"
gui_image_node *m_gui_image_node;
WheelScannerUI::WheelScannerUI(QWidget *parent)
: QMainWindow(parent),
ui(new Ui::WheelScannerUI)
{
ui->setupUi(this);
connect(m_gui_image_node, &gui_image_node::ReadyImage, this, &WheelScannerUI::updateWheelImage);
connect(m_gui_image_node, &gui_image_node::OpenHollander, this, &WheelScannerUI::Open_No_ID);
connect(this, &WheelScannerUI::ReadyHollander, m_gui_image_node, &gui_image_node::HolPub);
qDebug() << connect(this, &WheelScannerUI::ReadyHollander, m_gui_image_node, &gui_image_node::HolPub);
ui->lineEdit->setVisible(false);
QMainWindow::showFullScreen();
}
WheelScannerUI::~WheelScannerUI()
{
delete ui;
}
void WheelScannerUI::Open_No_ID(QString qsteve)
{
ui->lineEdit->setVisible(true);
}
void WheelScannerUI::on_lineEdit_returnPressed()
{
QString hol_num = ui->lineEdit->text();
Q_EMIT ReadyHollander(hol_num);
ui->lineEdit->setVisible(false);
ui->lineEdit->clear();
qDebug() << hol_num;
}
main windows .h
#ifndef WHEELSCANNERUI_H
#define WHEELSCANNERUI_H
#include <QMainWindow>
#include <QtSql>
#include <QSqlQuery>
#include <QSqlDatabase>
#include <QSqlQueryModel>
#include "gui_image_node.h"
#include <QPixmap>
#include <ros/ros.h>
#include <std_msgs/String.h>
#include <std_msgs/Int64.h>
#include <sensor_msgs/image_encodings.h>
#include <nodelet/nodelet.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <opencv2/highgui/highgui.hpp>
#include <pluginlib/class_list_macros.h>
#include <stdio.h>
#include <string.h>
#include <sstream>
#include <iostream>
extern gui_image_node *m_gui_image_node;
QT_BEGIN_NAMESPACE
namespace Ui { class WheelScannerUI; }
QT_END_NAMESPACE
class WheelScannerUI : public QMainWindow
{
Q_OBJECT
public:
WheelScannerUI(QWidget *parent = nullptr);
~WheelScannerUI();
WheelScannerUI *m_WheelScannerUI;
void connectionClose()
{
db.close();
db.removeDatabase(QSqlDatabase::defaultConnection);
}
bool connectionOpen()
{
db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("~/wheels.db");
if(!db.open())
{
qDebug()<<("Database failed to open");
return false;
}
else{
qDebug()<<("database connected");
return true;
}
}
public slots:
Q_SLOT void Open_No_ID(QString qsteve);
Q_SLOT void open_db_table(); //trigger with a ros callback?
signals:
Q_SIGNAL void ReadyHollander(QString);
private slots:
void on_lineEdit_returnPressed();
void on_Mode_Button_clicked();
private:
Ui::WheelScannerUI *ui;
QSqlDatabase db;
};
#endif // WHEELSCANNERUI_H
node cpp
#include "gui_image_node.h"
gui_image_node::gui_image_node()
{
}
bool gui_image_node::init(int argc, char** argv)
{
m_pThread = new QThread();
this->moveToThread(m_pThread);
connect(m_pThread, &QThread::started, this, &gui_image_node::run);
ros::init(argc, argv, "wheels_gui_image");
if ( ! ros::master::check() )
{
return false;
}
ros::start();
ros::Time::init();
ros::NodeHandle nh;
hollander_pub = nh.advertise<std_msgs::String>("/hollander_chat", 1);
hol_trigger = nh.subscribe("awaiting_hollander", 1, &gui_image_node::Hollander_Screen_trigger_callback, this);
m_pThread->start();
return true;
}
void gui_image_node::Hollander_Screen_trigger_callback(const std_msgs::String::ConstPtr& msg)
{
std::string steve = msg->data;
QString qsteve = QString::fromStdString(steve);
Q_EMIT OpenHollander(qsteve);
}
void gui_image_node::HolPub(QString hol_num)
{
qDebug() << "received number";
std::string hol_num_conv = hol_num.toUtf8().constData();
std_msgs::String msg;
msg.data = hol_num_conv;
hollander_pub.publish(msg);
}
nodes .h
#ifndef GUI_IMAGE_NODE_H
#define GUI_IMAGE_NODE_H
#include <ros/ros.h>
#include <nodelet/nodelet.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <opencv2/highgui/highgui.hpp>
#include <std_msgs/String.h>
#include <QMainWindow>
#include <QObject>
#include <QSharedDataPointer>
#include <QWidget>
#include <QThread>
#include <string>
#include <QMutex>
#include <QDebug>
#include <QDialog>
#include <stdio.h>
#include <string.h>
#include <sstream>
#include <iostream>
class gui_image_node : public QThread
{
Q_OBJECT
public:
gui_image_node();
~gui_image_node();
bool init(int argc, char** argv);
void Hollander_Screen_trigger_callback(const std_msgs::String::ConstPtr& msg);
protected:
public slots:
Q_SLOT void run();
Q_SLOT void HolPub(QString hol_num);
signals:
Q_SIGNAL void OpenHollander(QString);
private:
ros::Publisher hollander_pub;
ros::Subscriber hol_trigger;
QThread * m_pThread;
};
#endif // GUI_IMAGE_NODE_H
OK, I figured it out, connect(this, &WheelScannerUI::ReadyHollander, m_gui_image_node, &gui_image_node::HolPub, Qt::Directconnection);
Since this is being triggered from another thread, Directconnection allows the thread it is being emitted from to trigger the slot in a different thread.
i've created a custom progress bar, but when i call the SetValue() method the paintEvent method (overrided) is not called, so the progress bar show just the veryfirst value.
This is the Header grafica_progressbar.h
#ifndef GRAFICA_PROGRESSBAR_H
#define GRAFICA_PROGRESSBAR_H
#include <QWidget>
#include <QProgressBar>
#include <QPaintEvent>
#include <QPainter>
#include <QBrush>
#include <QStyle>
#include <QPen>
#include <QColor>
class grafica_ProgressBar : public QProgressBar
{
Q_OBJECT
public:
grafica_ProgressBar();
protected:
void paintEvent(QPaintEvent*) Q_DECL_OVERRIDE;
};
#endif // GRAFICA_PROGRESSBAR_H
and this is the cpp grafica_progressbar.cpp
#include "grafica_progressbar.h"
grafica_ProgressBar::grafica_ProgressBar()
{
}
void grafica_ProgressBar::paintEvent(QPaintEvent *)
{
int tmpValue = value();
int TopPos = QStyle::sliderPositionFromValue(minimum(), maximum(), tmpValue, width());
QPainter p(this);
if (tmpValue<maximum()*0.85)
{
p.setPen(Qt::green);
p.setBrush(QBrush(Qt::green));
}
else
{
p.setPen(QColor(255,51,51));
p.setBrush(QColor(255,51,51));
}
p.drawRect(0,0,TopPos,height());
p.setPen(Qt::gray);
p.setBrush(QBrush(Qt::lightGray));
p.drawRect(TopPos, 0, width(), height()); //riempio tutto il resto di grigio
p.setPen(Qt::black);
p.setBrush(QBrush(Qt::black));
p.drawText(0,0, width(), height(), Qt::AlignCenter, QString::number(tmpValue ) + " bar");
}
and this is the first call into the userinterface costructor
TestProgres = new grafica_ProgressBar();
ui->gridLayout->addWidget(TestProgres);
TestProgres->setMaximum(400);
TestProgres->setValue(300);
if i try to call TestProgres->setValue(200) inside a button, i can't see any refresh.
So, where's the problem?
The code starts to work after a "clean, rebuilt & run" operation.
I've edited the code just for showing the correct value.
Thanks to all!
I'm trying to have a QPushButton in my scene, but when I'm trying to add the QGraphicsProxyWidget to the scene, it crashes.
So here's the .cpp:
#include "upgradecromagnon.h"
#include "game.h"
#include <QGraphicsProxyWidget>
#include <qDebug>
extern Game *game;
UpgradeCromagnon::UpgradeCromagnon()
{
this->setRect(-50,0,150,50);
buttonAmelio = new QPushButton("salut");
teste();
}
void UpgradeCromagnon::teste()
{
QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget();
proxy->setWidget(buttonAmelio);
scene()->addItem(proxy);
}
and its .h:
#ifndef UPGRADECROMAGNON_H
#define UPGRADECROMAGNON_H
#include <QPainter>
#include <QGraphicsRectItem>
#include <QPushButton>
class UpgradeCromagnon: public QGraphicsRectItem
{
public:
UpgradeCromagnon();
void teste();
private:
QPushButton *buttonAmelio;
};
#endif // UPGRADECROMAGNON_H
Your UpgradeCromagnon constructor calls UpgradeCromagnon::teste which, in turn, calls QGraphicsItem::scene. At that point QGraphicsItem::scene must return a null pointer since there's no possible way the UpgradeCromagnon instance can have been added to a QGraphicsScene before its contructor has completed (not according to the code you've provided at any rate).
I'm creating a sort of drawable object class for mesh data and i'm getting this linker error. This is also on top of another class that handles the drawing of the meshes that was used in one of the Qt tutorials. I'm also using a QGLWidget to be the surface i'm drawing to. Here's what the header file looks for the first class.
#ifndef GLOBJECT_H
#define GLOBJECT_H
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QVector3D>
#include <QVector2D>
#include <QDebug>
#include <QFile>
struct VertexData
{
QVector3D position;
QVector2D texCoord;
QVector3D normal;
};
class GLObject
{
public:
GLObject();
VertexData *data;
GLushort *indices;
GLuint vboIds[2];
int faceCount, vertCount;
bool generateFromPLY(QString filename);
};
#endif // GLOBJECT_H
Here's the header for the other class.
#ifndef GEOMETRYENGINE_H
#define GEOMETRYENGINE_H
#include <QObject>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QVector2D>
#include <QVector3D>
#include <QFile>
#include <QDebug>
#include <QVector>
#include <globject.h>
class GeometryEngine : public QObject, protected QOpenGLFunctions
{
Q_OBJECT
public:
GeometryEngine();
~GeometryEngine();
void init();
void drawGeometry(QOpenGLShaderProgram *program);
//void drawCubeGeometry(QOpenGLShaderProgram *program);
bool generateFromPly(QString filename);
QVector<GLObject> drawables;
int drawableId = 0;
};
#endif // GEOMETRYENGINE_H
G:\Dropbox\GLSLDemo\globject.cpp:60: error: 'glGenBuffers' was not declared in this scope
glGenBuffers(2, vboIds);
along with the same error for the other gl calls.
Initially I had all the code in GeometryEngine to begin with. I didn't have a scope issue then. initilizeOpenGLFunctions() is called in GeometryEngine's init() if that's relevant.
^
QT OpenGL is weird. I think the QOpenGLFunctions maintains a common context. Also i'm bad at C++ and used protected wrong.
I've been learning OpenGL the past few weeks and after reading the Swiftless tuts and part of Nehe's tuts, along side with other articles concerning normals, scene graphs, bla bla, i've decided to create some sort of "framework", to allow me to insert newly learned code easier. So I decided to create a scenegraph/renderer combo, not that pretty, not that fast (prolly), but with the option to add just a new derived node class to render a new whatever feature i might just have read. So i look on the interwebz to see various examples on how to implement one and settle on this base class:
#pragma once
#ifndef NODE_H
#define NODE_H
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/glext.h>
#include <math.h>
#include <windows.h>
#include <list>
using namespace std;
class Node
{
public:
Node(void);
~Node(void);
//Node* parent;
void addChild(Node* node);
void removeChilds(Node* node);
virtual void traverse();
void kill();
protected:
std::list<Node*> childs;
};
#endif
.... from which i made this class:
#pragma once
#ifndef NODESPHERE_H
#define NODESPHERE_H
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/glext.h>
#include <math.h>
#include <windows.h>
#include "Various.h"
#include "Node.h"
class NodeSphere : public Node
{
public:
NodeSphere(double R, double H, double K, double Z, const int space);
~NodeSphere(){delete this;}
void traverse();
private:
float out[3];
int Radius;
int vhVertexCount;
Vert *vhVertices;
Normal *vhNormals,*vhVNormals;
TexCoord *vhTexCoords;
unsigned int vhVBOVertices;
unsigned int vhVBOTexCoords;
unsigned int vhVBONormals;
bool Init(void);
bool Normals(const int nIndex);
bool ReduceToUnit(void);
};
#endif
Now, i use freeglut to handle the window creation and the loop:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/glext.h>
#include <math.h>
#include "Scenegraph.h"
#include "View.h"
#include "Control.h"
#define WIDTH 800
#define HEIGHT 600
Scenegraph *bob;
View *myView;
Control *controler;
.................
.................
void main(int argc, char **argv)
{
glewInit();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(WIDTH,HEIGHT);
glutInitWindowPosition(0,0);
glutCreateWindow("Mediensoftware - Finale Übung");
bob = new Scenegraph();
myView = new View(WIDTH, HEIGHT, bob);
controler = new Control(myView);
glutDisplayFunc(display);
glutIdleFunc(idle);
glutReshapeFunc(resize);
glutKeyboardFunc(keyboard);
glutSpecialFunc(keyboard_s);
glutMainLoop();
}
The Scenegraph "bob" handles the creation of nodes like this:
Scenegraph::Scenegraph()
{
this->root = new Node();
this->sun = new NodeSphere(3,0,0,0,10);
this->sun_transform = new NodeTransform();
this->sun_tex = new NodeTexture("sunmap.bmp");
this->sun_mat = new NodeMaterial(1.0,0,1.0,0.7,0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0);
this->planet_earth = new NodeSphere(1,0,0,0,10);
this->planet_earth_transform = new NodeTransform(6,0,0);
this->planet_earth_tex = new NodeTexture("earthmap.bmp");
this->planet_earth_mat = new NodeMaterial(1.0,0,1.0,0.7,0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0);
this->moon = new NodeSphere(0.3,0,0,0,10);
this->moon_tex = new NodeTexture("moonmap.bmp");
this->moon_transform = new NodeTransform(1.5,0,0);
this->moon_mat = new NodeMaterial(1.0,0,1.0,0.7,0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0);
this->planet_venus = new NodeSphere(0.8,0,0,0,10);
this->planet_venus_transform = new NodeTransform(3,0,0);
this->planet_venus_tex = new NodeTexture("venusmap.bmp");
this->planet_venus_mat = new NodeMaterial(1.0,0,1.0,0.7,0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0);
this->planet_mars = new NodeSphere(0.6,0,0,0,10);
................................................................................................
this->root->addChild(this->sun_transform);
this->sun_transform->addChild(this->sun_mat);
this->sun_mat->addChild(this->sun_tex);
this->sun_tex->addChild(this->sun);
this->sun->addChild(this->planet_venus_transform);
this->planet_venus_transform->addChild(this->planet_venus_mat);
this->planet_venus_mat->addChild(this->planet_venus_tex);
...................................................................................................
}
The compiler doesn't see any errors and executes the code, but it receives an access violation here:
bool NodeSphere::Init(void){
glGenBuffersARB(1, &vhVBOVertices); // DERP here
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vhVBOVertices);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, this->vhVertexCount * 3 * sizeof(float), this->vhVertices, GL_STATIC_DRAW_ARB);
glGenBuffersARB(1, &vhVBONormals);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vhVBONormals);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, this->vhVertexCount * 3 * sizeof(float), this->vhVNormals, GL_STATIC_DRAW_ARB);
glGenBuffersARB(1, &vhVBOTexCoords);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vhVBOTexCoords);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, this->vhVertexCount * 2 * sizeof(float), this->vhTexCoords, GL_STATIC_DRAW_ARB);
delete [] vhVertices;
vhVertices = NULL;
delete [] vhTexCoords;
vhTexCoords = NULL;
delete [] vhNormals;
vhNormals = NULL;
delete [] vhVNormals;
vhVNormals = NULL;
return true;
}
The extensions are called in the View::initExtensions(), the init of the Scenegraph is done after the window creation, so.... i'm pretty sure it has something to do with pointers...
on previous programs i used the exact same code for VBO creation and it worked. The only difference is that the code used here is used in a Node*, while the previous ones were used in just Node (no pointer). But in any case, i'm gonna check if glew starts up well.
As for what video card i am using, on the laptop i have a crappy Intel integrated card, which should support OpenGL 1.5, but doesn't even have GLSL, and on the PC, a 6850. The thing is that i work a lot on the laptop, because of faculty and other stuff as well.
But anyway, the code for creating VBO's works, i mean, it has worked for the following:
#include <stdlib.h>
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <GL/glew.h>
#include <GL/gl.h> // Header File For The OpenGL32 Library
#include <GL/glu.h> // Header File For The GLu32 Library
#include <GL/glext.h>
#include <math.h>
#define PI 3.14159265f
class Vert{
public:
float x;
float y;
float z;
};
class Normal{
public:
float x;
float y;
float z;
};
class TexCoord{
public:
float u;
float v;
};
class Scenegraph {
private:
float out[3];
int Radius;
GLuint tID[2];
int vhVertexCount;
Vert *vhVertices;
Normal *vhNormals,*vhVNormals;
TexCoord *vhTexCoords;
unsigned int vhVBOVertices;
unsigned int vhVBOTexCoords;
unsigned int vhVBONormals;
bool Init(void);
bool Normals(const int nIndex);
bool ReduceToUnit(void);
public:
bool Create(double R, double H, double K, double Z, const int space);
void Render();
};
which is identical to NodeSphere, except it was statically declared. Thanks in advance.
Most likely, the error is occurring because the NodeSphere doesn't exist (or is no longer valid) when you try to call init().
You should probably move the resource initialization code into the constructor (that's generally what they're for) unless you need it to occur later on. It makes sense for the VBO to have a similar lifespan to the object, so creating and destroying them in the ctor/dtor should work and saves you the complexity of explicitly initializing.