OpenSceneGraph integration in Qt MainWindow - qt

I have the following code which is a modification of the code given by OpenSceneGraph (https://github.com/openscenegraph/osg/blob/master/examples/osgviewerQt/osgviewerQt.cpp) for integrating OSG with Qt:
OSGViewer.h
#ifndef OSGVIEWER_H
#define OSGVIEWER_H
#include <QTimer>
#include <QApplication>
#include <QGridLayout>
#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/MultiTouchTrackballManipulator>
#include <osgDB/ReadFile>
#include <osgQt/GraphicsWindowQt>
#include <QGLWidget>
class ViewerWidget : public QWidget, public osgViewer::CompositeViewer
{
public:
ViewerWidget(QWidget* parent = 0, osgViewer::ViewerBase::ThreadingModel threadingModel=osgViewer::CompositeViewer::SingleThreaded);
QWidget* addViewWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene );
osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name="", bool windowDecoration=false );
virtual void paintEvent( QPaintEvent* event ) { frame(); }
QTimer _timer;
};
#endif // OSGVIEWER_H
OSGViewer.cpp
#include "OSGViewer.h"
ViewerWidget::ViewerWidget(QWidget* parent, osgViewer::ViewerBase::ThreadingModel threadingModel)
{
setThreadingModel(threadingModel);
connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );
_timer.start( 10 );
}
QWidget* ViewerWidget::addViewWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )
{
osgViewer::View* view = new osgViewer::View;
addView( view );
osg::Camera* camera = view->getCamera();
camera->setGraphicsContext( gw );
const osg::GraphicsContext::Traits* traits = gw->getTraits();
camera->setClearColor( osg::Vec4(0, 0, 0, 1.0) );
camera->setViewport( new osg::Viewport(0, 0, this->width(), this->height()) );
camera->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0f, 10000.0f );
view->setSceneData( scene );
view->addEventHandler( new osgViewer::StatsHandler );
view->setCameraManipulator( new osgGA::MultiTouchTrackballManipulator );
gw->setTouchEventsEnabled( true );
return gw->getGLWidget();
}
osgQt::GraphicsWindowQt* ViewerWidget::createGraphicsWindow( int x, int y, int w, int h, const std::string& name, bool windowDecoration )
{
osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->windowName = name;
traits->windowDecoration = windowDecoration;
traits->x = x;
traits->y = y;
traits->width = w;
traits->height = h;
traits->doubleBuffer = true;
traits->alpha = ds->getMinimumNumAlphaBits();
traits->stencil = ds->getMinimumNumStencilBits();
traits->sampleBuffers = ds->getMultiSamples();
traits->samples = ds->getNumMultiSamples();
return new osgQt::GraphicsWindowQt(traits.get());
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "OSGViewer.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
//void onCreateView();
private:
Ui::MainWindow *ui;
osg::ref_ptr<ViewerWidget> m_osgViewer_right, m_osgViewer_left;
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_osgViewer_left = new ViewerWidget(this);
ui->left = m_osgViewer_left->addViewWidget(m_osgViewer_left->createGraphicsWindow(0,0,100,100), osgDB::readNodeFile("cessnafire.osg") );
m_osgViewer_left->show();
m_osgViewer_right = new ViewerWidget;
ui->right = m_osgViewer_right->addViewWidget(m_osgViewer_right->createGraphicsWindow(0,0,100,100), osgDB::readNodeFile("cow.osgt") );
m_osgViewer_right->show();
ui->gridLayout->addWidget( ui->left, 0, 0 );
ui->gridLayout->addWidget( ui->right, 0, 2 );
}
/* ------------------------------------------------------- */
MainWindow::~MainWindow()
{
delete ui;
}
Although I can render two objects using two different QWidgets in my MainWindow, I always have another two separate empty windows that pop up behind my MainWindow. If I close them, then I cannot render my models any more in my MainWindow. Any ideas how to solve this? I'm new to OpenSceneGraph.

Related

How to reuse the same window after clicking on other button?

I am trying to create an image viewer with slide show. When the user clicks on the play button, the viewer starts to show images. When the the user clicks on the stop button, the viewer stops to show images. After stopping, when the user clicks on the play button again, the viewer will continue to show the remaining images. My problem is that when the user clicks on the stop button and click on the play button again, I don't know how to reuse the same window created at the beginning to show the remaining images.
Button3 is the play button.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFileSystemModel>
#include "showpic.h"
#include <QBasicTimer>
#include <QTimer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_3_clicked();
void tick();
void on_pushButton_4_clicked();
private:
Ui::MainWindow *ui;
QFileSystemModel *model;
QString filesPath;
ShowPic *showpic;
QStringList filenames;
QStringList::const_iterator m_imageIt;
QTimer m_timer;
};
#endif // MAINWINDOW_H
showpic.h
#ifndef SHOWPIC_H
#define SHOWPIC_H
#include <QWidget>
namespace Ui {
class ShowPic;
}
class ShowPic : public QWidget
{
Q_OBJECT
public:
explicit ShowPic(QWidget *parent = 0);
~ShowPic();
private:
Ui::ShowPic *ui;
public:
void addPixmap(const QPixmap &pixmap);
};
#endif // SHOWPIC_H
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QFileDialog>
#include<QFileSystemModel>
#include<QStringList>
#include <QTreeView>
#include <QGraphicsScene>
#include <QTime>
#include <QDebug>
#include <iostream>
#include <QTimer>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
filenames.append("C:\\test\\image.jpg");
filenames.append("C:\\test\\apple.jpg");
filenames.append("C:\\test\\orange.jpg");
filenames.append("C:\\test\\lemon.jpg");
filenames.append("C:\\test\\grape.jpg");
m_timer.setInterval(1000);
connect(&m_timer, SIGNAL(timeout()), this, SLOT(tick()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::tick(){
showpic->addPixmap(*m_imageIt);
m_imageIt ++;
if(m_imageIt == filenames.end()){
m_timer.stop();
m_imageIt = filenames.begin();
}
}
void MainWindow::on_pushButton_3_clicked() //click on the play button
{
if(!filenames.isEmpty()){ // initial click
showpic = new ShowPic();
m_timer.start();
showpic->setWindowState(Qt::WindowMaximized);
showpic->show();
} else if( ) { // click on the play button again,
m_timer.start(); //???
showpic->setWindowState(Qt::WindowMaximized); //???
showpic->show(); //???
}
}
void MainWindow::on_pushButton_4_clicked() // click on the stop button
{
m_timer.stop();
}
showpic.cpp
#include "showpic.h"
#include "ui_showpic.h"
ShowPic::ShowPic(QWidget *parent) :
QWidget(parent),
ui(new Ui::ShowPic)
{
ui->setupUi(this);
ui->graphicsView->setScene(new QGraphicsScene);
ui->horizontalLayout->addWidget(ui->graphicsView);
this->setLayout(ui->horizontalLayout);
}
ShowPic::~ShowPic()
{
delete ui;
}
void ShowPic::addPixmap(const QPixmap &pixmap){
ui->horizontalLayout->addWidget(ui->graphicsView);
this->setLayout(ui->horizontalLayout);
ui->graphicsView->setScene(new QGraphicsScene);
ui->graphicsView->scene()->addPixmap(pixmap);
ui->graphicsView->fitInView(ui->graphicsView->scene()->itemsBoundingRect() ,Qt::KeepAspectRatio);
}
Else part of on_pushButton_3_clicked won't run in any case because filenames is being filled when MainWindow created. In your code, you're creating new showpic in every click.
Firstly, set showpic to NULL in constructor of MainWindow;
showpic = NULL;
And change on_pushButton_3_clicked method like this;
void MainWindow::on_pushButton_3_clicked() //click on the play button
{
if(showpic == NULL){
showpic = new ShowPic();
}
if(!showpic->isVisible()){
showpic->setWindowState(Qt::WindowMaximized);
showpic->show();
}
m_timer.start();
}
Lastly, i don't have QT now, so my answer may contains typo/syntax error.
This works for me. I tested the scene clearing method, and it worked fine for me. But here I decided to just store the pointer to the QGraphicsPixmapItem as a member variable, and just set a new pixmap to it, instead of clearing the scene constantly. Seems more elegant like this to me.
#include <QtWidgets>
class SlideView : public QWidget
{
Q_OBJECT
public:
SlideView(QWidget *parent = nullptr) : QWidget(parent)
{
setLayout(new QHBoxLayout);
layout()->addWidget(&view);
view.setScene(new QGraphicsScene(this));
pixmap_item = new QGraphicsPixmapItem;
view.scene()->addItem(pixmap_item);
}
void setPixmap(const QPixmap &pixmap)
{
pixmap_item->setPixmap(pixmap);
view.fitInView(view.scene()->itemsBoundingRect(), Qt::KeepAspectRatio);
}
private:
QGraphicsView view;
QGraphicsPixmapItem *pixmap_item = nullptr;
};
class MainWidget : public QWidget
{
Q_OBJECT
public:
MainWidget(QWidget *parent = nullptr) : QWidget(parent)
{
slide_iterator = slides.begin();
setLayout(new QHBoxLayout);
QPushButton *play_button = new QPushButton("Play");
QPushButton *stop_button = new QPushButton("Stop");
layout()->addWidget(play_button);
layout()->addWidget(stop_button);
connect(play_button, &QPushButton::clicked, this, &MainWidget::play);
connect(stop_button, &QPushButton::clicked, this, &MainWidget::stop);
connect(&timer, &QTimer::timeout, this, &MainWidget::showNextSlide);
}
public slots:
void play() {timer.start(1000); view.showMaximized(); view.activateWindow();}
void stop() {timer.stop();}
void showNextSlide()
{
QPixmap pixmap(*slide_iterator);
view.setPixmap(pixmap);
slide_iterator++;
if(slide_iterator == slides.end())
slide_iterator = slides.begin();
}
private:
QTimer timer;
QStringList slides{"one.png", "two.png", "three.png"};
QStringList::const_iterator slide_iterator;
SlideView view;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWidget w;
w.show();
return a.exec();
}
#include "main.moc"

QScrollArea and QVBoxLayout issues with dynamically added widgets

Im running into a weird issue with dynamically added widgets to a QVBoxLayout contained inside a QScrollArea. If I add the widgets it works as expected, however after all widgets are removed, there are still some artifacts on the screen. See screenshot bellow:
See the code bellow:
ui_mainwindow.h
/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created by: Qt User Interface Compiler version 5.2.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QScrollArea>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QWidget *centralWidget;
QVBoxLayout *verticalLayout_2;
QScrollArea *scrollArea;
QWidget *scrollAreaWidgetContents;
QHBoxLayout *horizontalLayout_2;
QVBoxLayout *verticalLayout;
QPushButton *pushButton;
QPushButton *pushButton_2;
QMenuBar *menuBar;
QToolBar *mainToolBar;
QStatusBar *statusBar;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QStringLiteral("MainWindow"));
MainWindow->resize(600, 396);
centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName(QStringLiteral("centralWidget"));
verticalLayout_2 = new QVBoxLayout(centralWidget);
verticalLayout_2->setSpacing(6);
verticalLayout_2->setContentsMargins(11, 11, 11, 11);
verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2"));
scrollArea = new QScrollArea(centralWidget);
scrollArea->setObjectName(QStringLiteral("scrollArea"));
scrollArea->setWidgetResizable(true);
scrollAreaWidgetContents = new QWidget();
scrollAreaWidgetContents->setObjectName(QStringLiteral("scrollAreaWidgetContents"));
scrollAreaWidgetContents->setGeometry(QRect(0, 0, 574, 246));
horizontalLayout_2 = new QHBoxLayout(scrollAreaWidgetContents);
horizontalLayout_2->setSpacing(6);
horizontalLayout_2->setContentsMargins(11, 11, 11, 11);
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
verticalLayout = new QVBoxLayout();
verticalLayout->setSpacing(6);
verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
horizontalLayout_2->addLayout(verticalLayout);
scrollArea->setWidget(scrollAreaWidgetContents);
verticalLayout_2->addWidget(scrollArea);
pushButton = new QPushButton(centralWidget);
pushButton->setObjectName(QStringLiteral("pushButton"));
verticalLayout_2->addWidget(pushButton);
pushButton_2 = new QPushButton(centralWidget);
pushButton_2->setObjectName(QStringLiteral("pushButton_2"));
verticalLayout_2->addWidget(pushButton_2);
MainWindow->setCentralWidget(centralWidget);
menuBar = new QMenuBar(MainWindow);
menuBar->setObjectName(QStringLiteral("menuBar"));
menuBar->setGeometry(QRect(0, 0, 600, 22));
MainWindow->setMenuBar(menuBar);
mainToolBar = new QToolBar(MainWindow);
mainToolBar->setObjectName(QStringLiteral("mainToolBar"));
MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
statusBar = new QStatusBar(MainWindow);
statusBar->setObjectName(QStringLiteral("statusBar"));
MainWindow->setStatusBar(statusBar);
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0));
pushButton->setText(QApplication::translate("MainWindow", "add one", 0));
pushButton_2->setText(QApplication::translate("MainWindow", "remove one", 0));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
ui->verticalLayout->addWidget(new QLabel("This is a label", this));
qDebug() << "Labels count: " << ui->verticalLayout->count();
}
void MainWindow::on_pushButton_2_clicked()
{
delete ui->verticalLayout->takeAt(0);
qDebug() << "Labels count: " << ui->verticalLayout->count();
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
It seems like I also have to remove the QLayoutItem AND the Widget, just removing the widget or the QLayoutItem (which I did try) doesn't work, both have to be removed, like so:
QLayoutItem *child = ui->verticalLayout->takeAt(0);
if (child)
{
delete child->widget();
delete child;
}

QSQLITE "Driver not loaded"

i have a problem with QSQLDATABASE. i'm using Qt 4.8.5
i get always Driver not loaded error .
i have check that QSQLITE driver is available
her is my code so far
article.h
#ifndef ARTICLE_H
#define ARTICLE_H
#include <QWidget>
#include <QtSql>
#include <QSqlDatabase>
namespace Ui {
class article;
}
class article : public QWidget
{
Q_OBJECT
public:
explicit article(QWidget *parent = 0);
~article();
void lastId(QString table);
bool changes();
void setChanges(bool change);
bool updates();
void setUpdates(bool update);
private slots:
void on_nouveaupushButton_clicked();
private:
Ui::article *ui;
bool m_detectChanges;
bool m_detectUpdates ;
};
#endif // ARTICLE_H
article.cpp
#include "article.h"
#include "ui_article.h"
#include <QMessageBox>
#include <databasemananger.h>
article::article(QWidget *parent) :
QWidget(parent),
ui(new Ui::article)
{
ui->setupUi(this);
m_detectChanges = false ;
m_detectUpdates = false;
// Setup
lastId("articles");
}
article::~article()
{
delete ui;
}
void article::lastId(QString table)
{
QSqlDatabase db = QSqlDatabase::database();
QSqlQuery query ;
QString queryString = "select seq from sqlite_sequence where name= ? ";
query.prepare(queryString);
query.addBindValue("articles");
if(!query.exec())
{
QMessageBox::critical(this,tr("Inventaire"),query.lastError().text());
return;
}
while(query.next())
{
ui->articleCodeLineEdit->setText("ART_" + QString::number(query.value(0).toInt() + 1));
return ;
}
if(ui->articleCodeLineEdit->text().isEmpty())
ui->articleCodeLineEdit->setText("ART_1");
}
bool article::changes()
{
return m_detectChanges ;
}
void article::setChanges(bool change)
{
m_detectChanges = change;
}
bool article::updates()
{
return m_detectUpdates;
}
void article::setUpdates(bool update)
{
m_detectUpdates = update ;
}
void article::on_nouveaupushButton_clicked()
{
// check changes
// get last id
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSqlDatabase>
#include <article.h>
#include <QtSql>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_actionAjouter_nouveau_article_triggered();
private:
Ui::MainWindow *ui;
QSqlDatabase *m_db ;
article *m_fenetreArticle;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QtGlobal>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_fenetreArticle = new article(this);
m_fenetreArticle->setWindowFlags(Qt::Window);
m_db = new QSqlDatabase;
// Base de données traitement
m_db->setHostName("localhost");
m_db->setDatabaseName("E:/apprendreQt/gestionstock6/database/gestionStock4.db");
m_db->setPassword("");
m_db->setUserName("");
if(!m_db->open())
QMessageBox::critical(this,"erreur connecting",m_db->lastError().text());
}
MainWindow::~MainWindow()
{
m_db->close();
QSqlDatabase::removeDatabase("gestionstock4.db");
delete ui;
}
void MainWindow::on_actionAjouter_nouveau_article_triggered()
{
m_fenetreArticle->show();
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Don't use m_db = new QSqlDatabase;.
See the documentation :
QSqlDatabase::QSqlDatabase()
Creates an empty, invalid QSqlDatabase object. Use addDatabase(), removeDatabase(), and database() to get valid QSqlDatabase objects.
You specify which driver to use when you call the addDatabase() function :
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
I figured out the probelm is cause by me
m_fenetreArticle needs the default database connexion , and i have creates
m_fenetreArticle object before creating the default connexion
mainwindow.cpp must be like so
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QtGlobal>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_db = new QSqlDatabase;
// Base de données traitement
m_db->setHostName("localhost");
m_db->setDatabaseName("E:/apprendreQt/gestionstock6/database/gestionStock4.db");
m_db->setPassword("");
m_db->setUserName("");
if(!m_db->open())
QMessageBox::critical(this,"erreur connecting",m_db->lastError().text());
m_fenetreArticle = new article(this);
m_fenetreArticle->setWindowFlags(Qt::Window);
}
MainWindow::~MainWindow()
{
m_db->close();
QSqlDatabase::removeDatabase("gestionstock4.db");
delete ui;
}
void MainWindow::on_actionAjouter_nouveau_article_triggered()
{
m_fenetreArticle->show();
}

some error with mousepressevent()

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMouseEvent>
#include <QDebug>
#include "my_qlabel.h"
#include<QTimer>
int px;
int py;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
tmrTimer = new QTimer(this);
connect(tmrTimer,SIGNAL(timeout()),this,SLOT(showthepositionofmouse()));
tmrTimer->start(20);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::showthepositionofmouse()
{
ui->plainTextEdit->appendPlainText(QString(" x , y = ")+QString::number(px)+QString::number(py));
}
void my_qlabel::mousePressEvent(QMouseEvent *event)
{
if (event->button()==Qt::RightButton){
px = event->x();
py = event->y();
}
}
i Want to display the position of Mouse clicked
i use ui->plainTextEdit->appendPlainText(QString(" x , y = ")+QString::number(px)+QString::number(py)); to display this position. although i click mouse,it only show x,y = 0 0. why that?
The py and px that are accessed in my_qlabel::mousePressEvent, are member variables of my_qlabel and are not visible to MainWindow::showthepositionofmouse.
If you want them to be visible you should send them using a signal and slot.
http://qt-project.org/doc/qt-4.8/signalsandslots.html
Here is a way to implement it:
In my_qlabel.h have something like this:
class my_qlabel : public QLabel
{
Q_OBJECT
signals:
void right_click_xy(int x, int y);
// ...constructor and other functions
public slots:
void mousePressEvent(QMouseEvent *event)
{
int px, py;
if (event->button()==Qt::RightButton){
px = event->x();
py = event->y();
emit right_click_xy(px, py);
}
}
}
In mainwindow.h have something like this:
class MainWindow : public QMainWindow
{
Q_OBJECT
// ... constructor and other functions
public slots:
void on_display_click_xy(int px, int py)
{
qDebug() << "Received xy over signal slot:" << px << py;
ui->plainTextEdit->appendPlainText(QString(" x , y = ")+QString::number(px)+QString::number(py));
}
}
And inside your MainWindow constructor put the following:
QObject::connect(ui->my_qlabel_instance, SIGNAL(right_click_xy(int,int)),
this, SLOT(on_display_click_xy(int, int)));
Another alternate way of doing this, but is isn't as kosher, would be to drill down into your ui object and access px and py that way.
qDebug() << ui->my_qlabel_instance->py;
But this is not as elegant, and isn't signaled the same way.
Another idea to look into is to use a QPoint object instead of two ints.
Hope that helps.
The whole idea is bad, you must process this event within my_qlabel class via signals and slots, not outside of it. I would suggest something like this (emit signal with coordinates of mouse click):
Header my_qlabel.h:
#ifndef MY_QLABEL_H
#define MY_QLABEL_H
#include <QLabel>
#include <QPoint>
#include <QEvent>
class my_qlabel : public QLabel
{
Q_OBJECT
public:
my_qlabel( const QString & text="", QWidget * parent = 0 );
signals:
void clicked(QPoint pos);
protected:
void mouseReleaseEvent ( QMouseEvent * event );
};
#endif // MY_QLABEL
Source my_qlabel.cpp:
#include "my_qlabel.h"
#include <QMouseEvent>
my_qlabel::my_qlabel( const QString & text, QWidget * parent )
:QLabel(parent)
{
setText(text);
}
void my_qlabel::mouseReleaseEvent ( QMouseEvent * event )
{
emit clicked(event->pos());
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "my_qlabel.h"
#include <QtGui/QWidget>
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void showthepositionofmouse(QPoint pos);
};
#endif // MAINWINDOW_H
and mainwindow.cpp:
#include "mainwindow.h"
#include <QDebug>
#include <QPoint>
#include <QHBoxLayout>
MainWindow::MainWindow(QWidget *parent) :
QWidget(parent)
{
my_qlabel* label=new my_qlabel("Text of my label",this);
label->setAlignment(Qt::AlignCenter);
QGridLayout *lay=new QGridLayout(this);
this->setLayout(lay);
lay->addWidget(label,0,0,1,1);
connect(label,SIGNAL(clicked(QPoint)),this,SLOT(showthepositionofmouse(QPoint)));
}
MainWindow::~MainWindow()
{
}
void MainWindow::showthepositionofmouse(QPoint pos)
{
qDebug()<< "Clicked, position="<<pos;
}

How to access a QLabel created in QtCreator Designer?

I created a few QLabel in my MainWindow using Qt Creator and opencv, but I have this error :
error: 'ui' was not declared in this scope
in the function filter_image(). I want to use label to show an image before and after doing some processing.
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include<QImage>
#include<QLabel>
static QImage IplImage2QImage(const IplImage *iplImage) {
int height = iplImage->height;
int width = iplImage->width;
if (iplImage->depth == IPL_DEPTH_8U && iplImage->nChannels == 3)
{
const uchar *qImageBuffer = (const uchar*)iplImage->imageData;
QImage img(qImageBuffer, width, height, QImage::Format_RGB888);
return img.rgbSwapped();
}
else if (iplImage->depth == IPL_DEPTH_8U && iplImage->nChannels == 1)
{
const uchar *qImageBuffer = (const uchar*)iplImage->imageData;
QImage img(qImageBuffer, width, height, QImage::Format_Indexed8);
QVector<QRgb> colorTable;
for (int i = 0; i < 256; i++)
{
colorTable.push_back(qRgb(i, i, i));
}
img.setColorTable(colorTable);
return img;
}
else
{
std::cout << "Image cannot be converted.";
return QImage();
}
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow() {
delete ui;
}
void MainWindow::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void filter_image(IplImage* img) {
IplImage* roi = cvCreateImage(cvGetSize(img), 8, 3);
cvCvtColor( img, roi, CV_RGB2GRAY );
cvSmooth(img,roi,CV_BLUR, 5, 0, 0, 0);
cvThreshold(roi,roi,100,255,CV_THRESH_BINARY);
IplImage *img_de = cvCloneImage(roi);
QImage qt_i = IplImage2QImage(img_de);
QLabel label_2;
// display on label
ui->label_2->setPixmap(QPixmap::fromImage(qt_i));//error line
// resize the label to fit the image
ui->label_2->resize(ui->label_2->pixmap()->size());
label_2.show();
}
void MainWindow::on_actionOpen_triggered() {
IplImage *frame = cvLoadImage(
QFileDialog::getOpenFileName(this,
"Ouvrir un fichier",
"/../../Fichiers Image",
"Image (*.jpg *.bmp *.jpeg)")
.toStdString().c_str(),3);
IplImage *img_des = cvCloneImage(frame);
QImage qt_im = IplImage2QImage(img_des);
QLabel label;
// display on label
ui->label->setPixmap(QPixmap::fromImage(qt_im));
// resize the label to fit the image
ui->label->resize(ui->label->pixmap()->size());
label.show();
filter_image(frame);
}
mainwindow.h
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
void changeEvent(QEvent *e);
public:
Ui::MainWindow *ui;
public slots:
void on_actionOpen_triggered();
};
ui_mainwindow.h
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QHeaderView>
#include <QtGui/QLabel>
#include <QtGui/QMainWindow>
#include <QtGui/QMenu>
#include <QtGui/QMenuBar>
#include <QtGui/QStatusBar>
#include <QtGui/QToolBar>
#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow{
public:
QAction *actionOpen;
QWidget *centralWidget;
QLabel *label;
QLabel *label_2;
QMenuBar *menuBar;
QMenu *menuFile;
QToolBar *mainToolBar;
QStatusBar *statusBar;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(600, 400);
actionOpen = new QAction(MainWindow);
actionOpen->setObjectName(QString::fromUtf8("actionOpen"));
centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
label = new QLabel(centralWidget);
label->setObjectName(QString::fromUtf8("label"));
label->setGeometry(QRect(290, 30, 271, 301));
label_2 = new QLabel(centralWidget);
label_2->setObjectName(QString::fromUtf8("label_2"));
label_2->setGeometry(QRect(20, 20, 281, 331));
MainWindow->setCentralWidget(centralWidget);
menuBar = new QMenuBar(MainWindow);
menuBar->setObjectName(QString::fromUtf8("menuBar"));
menuBar->setGeometry(QRect(0, 0, 600, 21));
menuFile = new QMenu(menuBar);
menuFile->setObjectName(QString::fromUtf8("menuFile"));
MainWindow->setMenuBar(menuBar);
mainToolBar = new QToolBar(MainWindow);
mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
statusBar = new QStatusBar(MainWindow);
statusBar->setObjectName(QString::fromUtf8("statusBar"));
MainWindow->setStatusBar(statusBar);
menuBar->addAction(menuFile->menuAction());
menuFile->addAction(actionOpen);
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0, QApplication::UnicodeUTF8));
actionOpen->setText(QApplication::translate("MainWindow", "Open", 0, QApplication::UnicodeUTF8));
label->setText(QString());
label_2->setText(QString());
menuFile->setTitle(QApplication::translate("MainWindow", "File", 0, QApplication::UnicodeUTF8));
} // retranslateUi};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
The method filter_image, which is where the error is occurring, is not a class method of MainWindow, so it doesn't have access to MainWindow's members (including ui).
You can do a couple of things: if it makes sense, make it part of the MainWindow class. Alternatively, you can pass the ui as a parameter:
void filter_image(Ui::MainWindow* ui, /*other params*/){...}
Also, you are making a local variable label_2 rather than taking the one from the gui.

Resources