Qt3DWindow crash trying to transform into QWidget - qt

Trying to create a 3D Render of my object and put it into QWidget app, but I got some problem with transforming Q3DWidget into QWidget. I'm a novice in Qt and I'm sorry in advance for some ridiculous mistakes, if I have em. There is how I attempted to do it:
Qt3DExtras::Qt3DWindow view;
Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity;
Qt3DCore::QEntity *model = new Qt3DCore::QEntity(rootEntity);
Qt3DExtras::QPhongMaterial *material = new Qt3DExtras::QPhongMaterial();
material->setDiffuse(QColor(125, 125, 125));
Qt3DRender::QMesh *modelMesh = new Qt3DRender::QMesh;
QUrl data = QUrl::fromLocalFile("C:\\CDH\\model.stl");
modelMesh->setMeshName("Device model");
modelMesh->setSource(data);
model->addComponent(modelMesh);
model->addComponent(material);
Qt3DRender::QCamera *camera = view.camera();
camera->lens()->setPerspectiveProjection(40.0f, 16.0f/9.0f, 0.1f, 1000.0f);
camera->setPosition(QVector3D(0, 0, 40.0f));
camera->setViewCenter(QVector3D(0, 0, 0));
Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(rootEntity);
Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity);
light->setColor("black");
light->setIntensity(0.8f);
lightEntity->addComponent(light);
Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity);
lightTransform->setTranslation(QVector3D(60, 0, 40.0f));
lightEntity->addComponent(lightTransform);
Qt3DExtras::QOrbitCameraController *camController = new
Qt3DExtras::QOrbitCameraController(rootEntity);
camController->setCamera(camera);
view.setRootEntity(rootEntity);
view.show();
QWidget *w = QWidget::createWindowContainer(&view);
//some widget handling
w->show();
It builds (MinGW 7.3.0) well, without errors and warning, but it just crashes when I try to launch an application.
Thanks in advance for your replies!

Related

QGraphicsPixmapItem doesn't show in QGraphicsScene

In the inherited class GraphicWidgetItem from QGraphicsItem, I create rectangles, a circle, and a picture. Everything is displayed except the picture. What am I doing wrong?
CustomItem::CustomItem( QObject *parent):
GraphicWidgetItem(parent)
{
QGraphicsRectItem *topLevel = new QGraphicsRectItem(this);
topLevel->setRect(0, 0, 20, 20);
topLevel->setBrush(Qt::gray);
topLevel->setPos(-30 , -30);
QGraphicsRectItem *lowLevel = new QGraphicsRectItem(this);
lowLevel->setRect(0, 0, 20, 20);
lowLevel->setBrush(Qt::red);
lowLevel->setPos(-30 , 60);
QGraphicsEllipseItem *circle = new QGraphicsEllipseItem(this);
circle->setBrush(Qt::green);
circle->setRect(0, 0, 20, 20);
QGraphicsPixmapItem* pi = new QGraphicsPixmapItem(QPixmap(":/icons/image"));
}
There is only 2 way for an item to appear in the scene:
Add directly using addItem().
Or be the children of an item that is already on the scene.
In your case "rectangles" and "circles" are shown because they are children of CustomItem but "pi" is not so it fails, the solution is to pass to "this" as parent:
QGraphicsPixmapItem* pi = new QGraphicsPixmapItem(QPixmap(":/icons/image"), this);
Or
QGraphicsPixmapItem* pi = new QGraphicsPixmapItem(QPixmap(":/icons/image"));
pi->setParent(this);

QObjectPicker not working with custom geometry mesh and renderer

I have set up a simple 3d scene with a custom QGeometryRenderer and QGeometry. The custom QGeometry is loaded from a ply file.
class ColorMeshGeometry : public Qt3DRender::QGeometry
{
Q_OBJECT
public:
ColorMeshGeometry(QString meshFile, ColorMeshRenderer *parent);
~ColorMeshGeometry();
void GeometryCenter(QVector3D* center);
};
class ColorMeshRenderer : public Qt3DRender::QGeometryRenderer
{
ColorMeshGeometry* m_geometry;
Q_OBJECT
public:
explicit ColorMeshRenderer(QString meshFile, Qt3DCore::QNode *parent = 0)
{
m_geometry = new ColorMeshGeometry(meshFile, this);
setGeometry(m_geometry);
}
~ColorMeshRenderer();
void ViewCenter(QVector3D* center);
};
And here is the code to set it all up:
uto view = new Qt3DExtras::Qt3DWindow();
auto container = createWindowContainer(view, this);
auto rootEntity = new Qt3DCore::QEntity();
ColorMeshRenderer* mesh = new ColorMeshRenderer(filename, rootEntity);
view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x111111)));
view->camera()->lens()->setPerspectiveProjection(45.0f, view->width()/view->height(), 0.01f, 100000.0f);
view->camera()->setPosition(QVector3D(0.f, -512.f, 500.0f));
view->camera()->setViewCenter(QVector3D(0, 0, 0));
auto material = new Qt3DExtras::QPerVertexColorMaterial(rootEntity);
auto picker = new Qt3DRender::QObjectPicker(rootEntity);
picker->setHoverEnabled(false);
picker->setDragEnabled(false);
auto plyEntity = new Qt3DCore::QEntity(rootEntity);
plyEntity->addComponent(mesh);
plyEntity->addComponent(material);
plyEntity->addComponent(picker);
connect(picker, &Qt3DRender::QObjectPicker::pressed, this, &ViewerWidget::picker_Clicked);
Qt3DExtras::QOrbitCameraController *camController = new Qt3DExtras::QOrbitCameraController(rootEntity);
camController->setCamera(view->camera());
view->setRootEntity(rootEntity);
The QObjectPicker::pressed event is never fired. If I use the Qt3DExtras::QTorusMesh instead, the pressed event is fired. What else needs to be implemented for the QObjectPicker to work with a custom mesh?
Edit:
Full sample code can be found here.
The fix for this ended up being the Perspective Projection. The back pane of the project ended up being way to far way, the fix is:
view->camera()->lens()->setPerspectiveProjection(45.0f, view->width()/view->height(), 0.01f, 5000.0f);

QTable and checkbox signal/slot

I'm newbie with QT and have read many topics, but I just don't get it. I hope that someone could help me with this.
So, I have created a loop where i add QTables in QGroupBoxes. Table's 2nd column is meant for QCheckBoxes and first column is meant for condition text, which changes when checkbox is ticked.
Everything is working except the text won't change. So problem should be in the signal. I just can't figure it out :(
I would be glad for any help :)
inputBox = new QGroupBox();
QScrollArea *boxScroll = new QScrollArea();
QHBoxLayout *boxLayout = new QHBoxLayout();
boxTable = new QTableWidget();
inputBox->setLayout(boxLayout);
boxLayout->addWidget(boxTable);
boxTable->verticalHeader()->setVisible(false);
boxTable->setRowCount(24);
boxTable->setColumnCount(5);
boxTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
boxTable->setHorizontalHeaderItem(0, new QTableWidgetItem("ID"));
boxTable->setHorizontalHeaderItem(1, new QTableWidgetItem("State"));
boxTable->setHorizontalHeaderItem(2, new QTableWidgetItem("Enable"));
for (int i=0; i<24; i++)
{
inCheck = new QCheckBox();
iCheckLabel = new QLabel();
QTableWidgetItem *id = new QTableWidgetItem();
QTableWidgetItem *state = new QTableWidgetItem();
QTableWidget *checkWidget = new QTableWidget();
QHBoxLayout *checkLayout = new QHBoxLayout();
checkLayout->setAlignment(Qt::AlignCenter);
checkLayout->setContentsMargins(0,0,0,0);
checkLayout->addWidget(inCheck);
checkWidget->setLayout(checkLayout);
id->setText(QString::number(i));
id->setTextAlignment(Qt::AlignCenter);
id->setFlags(id->flags() & ~Qt::ItemIsEditable);
state->setText("Off");
state->setTextAlignment(Qt::AlignCenter);
state->setFlags(state->flags() & ~Qt::ItemIsEditable);
state->setTextColor(Qt::red);
boxTable->setItem(i, 0, id);
boxTable->setItem(i, 1, state);
boxTable->setCellWidget(i, 2, checkWidget);
connect(checkWidget, SIGNAL(cellChanged(int,int)), this, SIGNAL(inCheckChecked(int, int)));
}
inputBox->setMinimumSize(350, 450);
inputBox->setTitle(title);
ui->scrollAreaWidgetContents->layout()->addWidget(inputBox);
void Project::inCheckChecked(int row, int col)
{
QTableWidgetItem *item = boxTable->item(row, col);
if (item->checkState() == true)
{
qDebug("is checked");
}
}
You do something very strange here. You set a layout to your table widget and then add a check box to that layout, then you add this table widget to another table widget. Why? You could just use QTableWidget::setItem(int row, int column, QTableWidgetItem * item) to add a check box, like you use it for id and state items. Just make it a checkable item.
for (int i=0; i<24; i++)
{
QTableWidgetItem *id = new QTableWidgetItem();
QTableWidgetItem *state = new QTableWidgetItem();
QTableWidgetItem *checkItem = new QTableWidgetItem();
...
checkItem->setCheckState(Qt::Unchecked); // shuold be enough to make it checkable..
//you can also set the needed flags
boxTable->setItem(i, 0, id);
boxTable->setItem(i, 1, state);
boxTable->setItem(i, 2, checkItem);
}
Then you just connect the signal from boxTable to your slot, which will notify you when the checkbox state is changed.
In this code, there is bug in below line
connect(checkWidget, SIGNAL(cellChanged(int,int)), this, SIGNAL(inCheckChecked(int, int)));
For using connect, according to your implementation, you want to connect one signal and one slot, that consumes that signal. It should be as below :
connect(checkWidget, SIGNAL(cellChanged(int,int)), this, SLOT(inCheckChecked(int, int)));
Get More info on Signals and Slots here

QGraphicScene Pop Ups for a second then vanishes

I have a all my code inside the constructor of a mainWindow. The problem is that the display only pop ups for a second and than vanishes. Any help will be much appreciated . Following is the code.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QPixmap kineticPix(":/images/kinetic.png");
QPixmap bgPix(":/images/Time-For-Lunch-2.jpg");
QGraphicsScene scene(-350, -350, 700, 700);
QGraphicsItem *buttonParent = new QGraphicsRectItem;
Button *ellipseButton = new Button(QPixmap(":/images/ellipse.png"), buttonParent);
Button *figure8Button = new Button(QPixmap(":/images/figure8.png"), buttonParent);
Button *randomButton = new Button(QPixmap(":/images/random.png"), buttonParent);
Button *tiledButton = new Button(QPixmap(":/images/tile.png"), buttonParent);
Button *centeredButton = new Button(QPixmap(":/images/centered.png"), buttonParent);
ellipseButton->setPos(-100, -100);
figure8Button->setPos(100, -100);
randomButton->setPos(0, 0);
tiledButton->setPos(-100, 100);
centeredButton->setPos(100, 100);
scene.addItem(buttonParent);
buttonParent->scale(0.75, 0.75);
buttonParent->setPos(200, 200);
buttonParent->setZValue(65);
}
You have created the scene on the stack and not assigned it to a member variable, so as soon as control leaves the constructor it is deleted.

QWidget::setLayout error : Attempting to set QLayout [...], which already has a layout

On execution (no compile error) I get on the console
QWidget::setLayout: Attempting to set QLayout "" on CGSearchResult "",
which already has a layout
I am using the following code:
CGSearchResult::CGSearchResult(QWidget *parent) : QWidget(parent)
{
initControls();
SetTableContent();
}
void CGSearchResult::initControls()
{
backButton = new QPushButton(tr("&Back"));
connect(backButton, SIGNAL(clicked()), this, SLOT(showHome()));
model=new QStandardItemModel();
QWidget::setFont(QFont("Courier New", 8, QFont::Bold));
searchTable = new QTableView(this);
searchTable->showGrid();
searchTable->resize(720,400);
searchTable->horizontalHeader()->setDefaultSectionSize(170);
searchTable->verticalHeader()->setDefaultSectionSize(50);
searchTable->verticalHeader()->hide();
searchTable->horizontalHeader()->setResizeMode(QHeaderView::Fixed);
searchTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
QGridLayout *layout = new QGridLayout();
layout->addWidget(backButton, 0, 0, 1, 1);
layout->addWidget(searchTable, 2, 0, 1, 1);
setLayout(layout);
}
http://qt-project.org/doc/qt-4.8/qwidget.html#setLayout
If there already is a layout manager installed on this widget, QWidget won't let you install another. You must first delete the existing layout manager (returned by layout()) before you can call setLayout() with the new layout.

Resources