I am trying to apply a metalic material texture to a 3D extruded text mesh.
I have based my example code on this:
https://code.woboq.org/qt5/qt3d/examples/qt3d/3d-text/main.cpp.html
The example uses the QPhongMaterial. I naively thought I could simply
replace that material by QMetalRoughMaterial which I tried.
#include <QCoreApplication>
#include <Qt3DCore/Qt3DCore>
#include <Qt3DExtras/Qt3DExtras>
#include <Qt3DExtras/QExtrudedTextMesh>
int main(int argc, char *argv[])
{
QGuiApplication a(argc, argv);
Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow();
view->setTitle(QStringLiteral("3D Text CPP"));
view->defaultFrameGraph()->setClearColor(QColor("white"));
auto *root = new Qt3DCore::QEntity();
//Light
Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(root);
Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity);
light->setColor("white");
light->setIntensity(0.5);
lightEntity->addComponent(light);
//auto *textMaterial = new Qt3DExtras::QPhongMaterial(root);
auto *textMaterial = new Qt3DExtras::QMetalRoughMaterial(root);
auto *text = new Qt3DCore::QEntity(root);
auto *textMesh = new Qt3DExtras::QExtrudedTextMesh();
auto *textTransform = new Qt3DCore::QTransform();
QFont font("Arial", 32, -1, false);
textTransform->setTranslation(QVector3D(-2.45f, 2.0 * .5f, 0));
textTransform->setScale(.8f);
textMesh->setDepth(.25f);
textMesh->setFont(font);
textMesh->setText("TEST");
//FOR PHONG MATERIAL
//textMaterial->setDiffuse(QColor("white"));
//textMaterial->setShininess(1.0);
//textMaterial->setSpecular(QColor("white"));
//FOR METAL
textMaterial->setBaseColor(QColor("blue"));
textMaterial->setMetalness(1.0);
textMaterial->setRoughness(0.2);
//textMaterial->setNormal(...)); //<-- what needs to come here?
text->addComponent(textMaterial);
text->addComponent(textMesh);
text->addComponent(textTransform);
// Camera
float aspect = static_cast<float>(view->screen()->size().width()) / view->screen()->size().height();
Qt3DRender::QCamera *camera = view->camera();
camera->lens()->setPerspectiveProjection(65.f, aspect, 0.1f, 100.f);
camera->setPosition(QVector3D(0, 1, 3));
camera->setViewCenter(QVector3D(0, 1, 0));
auto *cameraController = new Qt3DExtras::QOrbitCameraController(root);
cameraController->setCamera(camera);
view->setRootEntity(root);
view->show();
return a.exec();
}
With the code above, I see no text in the app window, whereas it works fine when using QPhongMaterial.
What am I missing here?
Related
I just recently started to use QT3D for a sideproject at work. And i'm surprised how fast you get something that looks pretty decent (at least for my case).
But i still have an issue with rendering speed and CPU usage.
I've written a small test program to showcase this (see below).
As we use Ubuntu i though it may be an issue with the NVIDIA driver but i tested it at home on my Windows PC as well.
And had the same results:
CPU usage is very high - 100% on one Core all the time.
GPU usage show no real difference if the application is running or not.
So my best guess is that it uses software rendering instead of the hardware?
Any ideas?
The example just draws 2000 Cuboids with random sizes on random positions with a light source above.
#include <QGuiApplication>
#include <QRandomGenerator>
#include <QHBoxLayout>
#include <Qt3DRender/QCamera>
#include <Qt3DCore/QEntity>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtGui/QScreen>
#include <Qt3DCore/QTransform>
#include <Qt3DCore/QAspectEngine>
#include <Qt3DExtras/QForwardRenderer>
#include <Qt3DRender/QPointLight>
#include <Qt3DExtras/QCuboidMesh>
#include <Qt3DExtras/QDiffuseSpecularMaterial>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QOrbitCameraController>
int main(int argc, char **argv)
{
//basic window/widget stuff
QApplication app(argc, argv);
Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow();
view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x4d4d4f)));
QWidget *container = QWidget::createWindowContainer(view);
QSize screenSize = view->screen()->size();
container->setMinimumSize(QSize(200, 100));
container->setMaximumSize(screenSize);
QWidget *widget = new QWidget;
QHBoxLayout *hLayout = new QHBoxLayout(widget);
hLayout->addWidget(container, 1);
//root entity
Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
view->setRootEntity(rootEntity);
//setup camera
view->camera()->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 10.0f, 5000.0f);
view->camera()->setPosition(QVector3D(0, 0, 3000));
view->camera()->setUpVector(QVector3D(0, 1, 0));
view->camera()->setViewCenter(QVector3D(0, 0, 0));
//orbit camera controller
Qt3DExtras::QOrbitCameraController *camController = new Qt3DExtras::QOrbitCameraController(rootEntity);
camController->setCamera(view->camera());
camController->setLookSpeed(500);
//add light
Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(rootEntity);
Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity);
light->setColor("white");
light->setIntensity(1);
lightEntity->addComponent(light);
Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity);
lightTransform->setTranslation(QVector3D(0, 5000, 0));
lightEntity->addComponent(lightTransform);
//add objects
QRandomGenerator rng(1234);
for(int i = 0; i <= 2000; i++)
{
Qt3DCore::QEntity* shapeEntity = new Qt3DCore::QEntity(rootEntity);
Qt3DExtras::QCuboidMesh* mesh = new Qt3DExtras::QCuboidMesh();
mesh->setXExtent(int(rng.generate() % 30)+20);
mesh->setYExtent(int(rng.generate() % 30)+20);
mesh->setZExtent(int(rng.generate() % 30)+20);
shapeEntity->addComponent(mesh);
Qt3DExtras::QDiffuseSpecularMaterial *material = new Qt3DExtras::QDiffuseSpecularMaterial();
material->setAmbient(QColor(Qt::red).darker(150));
material->setDiffuse(QColor(Qt::red));
shapeEntity->addComponent(material);
Qt3DCore::QTransform* pTrans = new Qt3DCore::QTransform();
pTrans->setTranslation(QVector3D(int(rng.generate() % 2000)-1000, int(rng.generate() % 2000)-1000, int(rng.generate() % 2000)-1000));
shapeEntity->addComponent(pTrans);
}
//show
widget->show();
widget->resize(1200, 800);
return app.exec();
}
I want to fit (child) widget into the parent widget size. So if the parent window is too small to display all the elements of the child widget the QScrollArea should appear otherwise it should be invisible.
I have attached the pictures for a better understanding.
The black box is where I want my scroll to appear. Since when we reduce the size of the window, sometimes you can't see the scroll bar (as displayed in the below picture) it doesn't look elegant enough for big projects.
Please help me with the same, thanks in advance.
Here's the sample code that I used for example:
int main(int argc, char *argv[]){
QApplication a(argc, argv);
QScrollPractice w;
QDialog * dlg = new QDialog();
//dlg->setGeometry(100, 100, 260, 260);
dlg->setMinimumSize(150, 200);
QScrollArea *scrollArea = new QScrollArea(dlg);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scrollArea->setWidgetResizable(true);
//scrollArea->setGeometry(10, 10, 200, 200);
//scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Ignored);
//QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
scrollArea->setSizePolicy(sizePolicy);
QWidget *widget = new QWidget(scrollArea);
scrollArea->setWidget(widget);
QVBoxLayout *layout = new QVBoxLayout(widget);
widget->setLayout(layout);
for (int i = 0; i < 10; i++)
{
QPushButton *button = new QPushButton(QString("%1").arg(i));
layout->addWidget(button);
}
dlg->show();
return a.exec();
}
Your Dialog is missing a layout as well. Thats the reason the scrollArea Widget isnt spread out across the dialog.
#include <QApplication>
#include <QDialog>
#include <QScrollArea>
#include <QVBoxLayout>
#include <QPushButton>
int main(int argc, char* argv[]){
QApplication a(argc, argv);
QDialog* dlg = new QDialog();
dlg->setMinimumSize(150, 200);
QScrollArea* scrollArea = new QScrollArea(dlg);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scrollArea->setWidgetResizable(true);
QWidget* widget = new QWidget(scrollArea);
scrollArea->setWidget(widget);
QVBoxLayout* dlgLayout = new QVBoxLayout();
dlg->setLayout( dlgLayout );
dlgLayout->addWidget( scrollArea );
QVBoxLayout* layout = new QVBoxLayout(widget);
widget->setLayout(layout);
for (int i = 0; i < 10; i++)
{
QPushButton* button = new QPushButton(QString("%1").arg(i));
layout->addWidget(button);
}
dlg->show();
return a.exec();
}
I modified your code to make it run and compileable, also I added antoher QVBoxLayout and added it to the dialog. Then the scrollArea gets added to that Layout. Hope this helps.
I am trying to add data labels in LineChart using Qt Charts
like this Image.
I am not able to figure out how I can do that. Any help will be appreciated.
I am using this example https://doc.qt.io/qt-5/qtcharts-linechart-example.html
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLineSeries *series = new QLineSeries();
series->append(0, 6);
series->append(2, 4);
series->append(3, 8);
series->append(7, 4);
series->append(10, 5);
QChart *chart = new QChart();
chart->legend()->hide();
chart->addSeries(series);
chart->createDefaultAxes();
chart->setTitle("Simple line chart example");
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(400, 300);
window.show();
return a.exec();
}
I get following output
I want something like this
Have you tried to set the labels to visible?
QLineSeries *series = new QLineSeries();
series->setPointLabelsVisible(true); // is false by default
series->setPointLabelsColor(Qt::black);
series->setPointLabelsFormat("#yPoint");
I'm try to create a GUI application.
The main window, a QMainWindow, contains 9 labels with fixed size and also the size of the main window.
I tried to make it programmatically without Qt GUI Designer. The project is built without error but I cannot see any label nor layout shown on the main window. it's just blank.
Here is my source code:
WCwindow::WCwindow()
{
// initialize widgets with text
CAM111 = new QLabel("CAM 01");
CAM121 = new QLabel("CAM 02");
CAM131 = new QLabel("CAM 03");
CAM211 = new QLabel("CAM 04");
CAM221 = new QLabel("CAM 05");
CAM231 = new QLabel("CAM 06");
CAM311 = new QLabel("CAM 07");
CAM321 = new QLabel("CAM 08");
CAM331 = new QLabel("CAM 09");
CAM111->setFixedSize(wcW,wcH);
CAM121->setFixedSize(wcW,wcH);
CAM131->setFixedSize(wcW,wcH);
CAM211->setFixedSize(wcW,wcH);
CAM221->setFixedSize(wcW,wcH);
CAM231->setFixedSize(wcW,wcH);
CAM311->setFixedSize(wcW,wcH);
CAM321->setFixedSize(wcW,wcH);
CAM331->setFixedSize(wcW,wcH);
QGridLayout *layout = new QGridLayout;
layout->addWidget(CAM111,0,0);
layout->addWidget(CAM121,0,1);
layout->addWidget(CAM131,0,2);
layout->addWidget(CAM211,1,0);
layout->addWidget(CAM221,1,1);
layout->addWidget(CAM231,1,2);
layout->addWidget(CAM311,2,0);
layout->addWidget(CAM321,2,1);
layout->addWidget(CAM331,2,2);
setLayout(layout);
setWindowTitle("Camera Window");
setFixedSize(1000, 800);
}
of course, the class is initialized and evoked in main.cpp:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
WCwindow *WCwin = new WCwindow;
WCwin->show();
return app.exec();
}
what kind of bug am I having??
The code below works fine. The problem was in the code you weren't showing. When you use a QMainWindow, as you've eventually admitted to doing, you need to set its centralWidget with a new widget that you construct.
// main.cpp
#include <QVector>
#include <QMainWindow>
#include <QLabel>
#include <QGridLayout>
#include <QApplication>
class WCwindow : public QMainWindow
{
public:
WCwindow();
private:
QVector<QLabel*> cams;
QLabel* cam(int r, int c) const {
return cams[r*3 + c];
}
};
WCwindow::WCwindow()
{
QGridLayout *layout = new QGridLayout;
for (int i = 1; i < 10; ++ i) {
QLabel * const label = new QLabel(QString("CAM %1").arg(i, 2, 10, QLatin1Char('0')));
label->setFixedSize(200, 50);
layout->addWidget(label, (i-1) / 3, (i-1) % 3);
cams << label;
}
QWidget * central = new QWidget();
setCentralWidget(central);
centralWidget()->setLayout(layout);
setWindowTitle("Camera Window");
setFixedSize(1000, 800);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
WCwindow win;
win.show();
return app.exec();
}
Is WCwindow a subclass of QMainWindow? In that case i would advise to remove the layout from your window in the GUI editor by clicking the "break layout" button in the top bar, then use the following:
//setup all your labels and layout ...
//creating a QWidget, and setting the WCwindow as parent
QWidget * widget = new QWidget(this);
//set the gridlayout for the widget
widget->setLayout(layout);
//setting the WCwindow's central widget
setCentralWidget(widget);
I am trying to force a container size of 200x100, while adding child controls that are spread over an area larger than 200x100. I expect to have a scroll bar when I exceed the size of the viewport, but the entire container window gets resized.
how do I force a container size of 200x100 and still get scroll bars that'll allow me to scroll down and see the rest of the content?
#include <QApplication>
#include <QPushButton>
#include <QScrollArea>
#include <QGridLayout>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget container;
container.setGeometry(QRect(600,300,200,100));
QGridLayout layout(&container);
QPushButton *aa = new QPushButton(QString("a"));
aa->setGeometry(QRect(10,10,100,30));
layout.addWidget(aa, 0, 0);
QPushButton *b = new QPushButton(QString("b"));
b->setGeometry(QRect(10,40,100,30));
layout.addWidget(b, 1, 0);
QPushButton *c = new QPushButton(QString("c"));
c->setGeometry(QRect(10,70,100,30));
layout.addWidget(c, 2, 0);
QPushButton *d = new QPushButton(QString("d"));
d->setGeometry(QRect(10,100,100,30));
layout.addWidget(d, 3, 0);
QPushButton *e = new QPushButton(QString("e"));
e->setGeometry(QRect(10,130,100,30));
layout.addWidget(e, 4, 0);
QPushButton *f = new QPushButton(QString("f"));
f->setGeometry(QRect(10,160,100,30));
layout.addWidget(f, 5, 0);
QPushButton *g = new QPushButton(QString("g"));
g->setGeometry(QRect(10,190,100,30));
layout.addWidget(g, 6, 0);
QPushButton *h = new QPushButton(QString("h"));
h->setGeometry(QRect(10,220,100,30));
layout.addWidget(h, 7, 0);
QScrollArea area;
area.setLayout(&layout);
area.setWidget(&container);
area.show();
return a.exec();
}
Set the size of the QScrollArea using setGeometry(), then use area.setSizePolicy(QSizePolicy::Fixed).