reading data from linux input on embedded board - qt

i compiled the following code for arm9 board. whenever i press any key the event should be detected.
keypress.ccp:
#include "keypress.h"
#include <QApplication>
#include <QKeyEvent>
KeyPress::KeyPress(QWidget *parent) :
QWidget(parent)
{
myLabel = new QLabel("LABEL");
mainLayout = new QVBoxLayout;
mainLayout->addWidget(myLabel);
setLayout(mainLayout);
}
void KeyPress::keyPressEvent(QKeyEvent *event)
{
if(event->key() == Qt::Key_A)
{
myLabel->setText("You pressed A");
}
}
void KeyPress::keyReleaseEvent(QKeyEvent *event)
{
if(event->key())
{
qDebug()<<"key released";
}
if(event->key() == Qt::Key_A)
{
myLabel->setText("You released A");
}
}
keypress.h:
#ifndef KEYPRESS_H
#define KEYPRESS_H
#include <QWidget>
#include <QtGui>
class KeyPress : public QWidget
{
Q_OBJECT
public:
KeyPress(QWidget *parent = 0);
protected:
void keyPressEvent(QKeyEvent *);
void keyReleaseEvent(QKeyEvent *);
private:
QLabel *myLabel;
QVBoxLayout *mainLayout;
};
#endif // KEYPRESS_H
main.cpp
#include <QtGui>
#include "keypress.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qDebug()<<"test";
KeyPress *keyPress = new KeyPress();
keyPress->show();
return a.exec();
}
using external key pad.
qt configuration:
/configure -embedded arm -xplatform qws/linux-arm-gnueabi-g++ -little-endian -qt-gfx-linuxfb -qt-gfx-qvfb -qt-kbd-tty -qt-kbd-qvfb -qt-kbd-linuxinput -qt-mouse-linuxinput -qt-mouse-qvfb -qt-mouse-pc -declarative -confirm-license
on board: export QWS_KEYBOARD="LinuxInput:/dev/input/event0"
when i run cat /dev/input/event0 | hexdump i am able to recieve keycodes for the key pressed. but when i run the the executable keypad is not responding. am i missing something? if so what else i should do to make the keypad work??

Related

Couldn't render OpenGLES context in Qt

I am trying to use OpenGLES in a desktop platform. I have a class whose name is GraphicsViewer which is derived from QOpenGLWidget. When I set the QSurfaceFormat::renderableType to QSurfaceFormat::OpenGLES, I get the following errors and nothing is drawn on the widget. Can you help me to create an OpenGLES context in a desktop platform? My OS is Windows 10 and my Qt version is 5.12.3.
Errors:
QOpenGLWidget: Failed to create context
QOpenGLWidget: Failed to create context
qt.qpa.backingstore: composeAndFlush: QOpenGLContext creation failed
QOpenGLWidget: Failed to create context
qt.qpa.backingstore: composeAndFlush: makeCurrent() failed
qt.qpa.backingstore: composeAndFlush: makeCurrent() failed
Here is my codes...
main.cpp
#include "QtOpenGLES.h"
#include <QApplication>
#include <QSurfaceFormat>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSurfaceFormat f;
f.setVersion(2, 0);
f.setRenderableType(QSurfaceFormat::OpenGLES);
QSurfaceFormat::setDefaultFormat(f);
QtOpenGLES w;
w.show();
return a.exec();
}
QtOpenGLES.h
#ifndef QTOPENGLES_H
#define QTOPENGLES_H
#include <QMainWindow>
namespace Ui {
class QtOpenGLES;
}
class QtOpenGLES : public QMainWindow
{
Q_OBJECT
public:
explicit QtOpenGLES(QWidget *parent = nullptr);
~QtOpenGLES();
private:
Ui::QtOpenGLES *ui;
};
#endif // QTOPENGLES_H
QtOpenGLES.cpp
#include "QtOpenGLES.h"
#include "ui_QtOpenGLES.h"
QtOpenGLES::QtOpenGLES(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::QtOpenGLES)
{
ui->setupUi(this);
}
QtOpenGLES::~QtOpenGLES()
{
delete ui;
}
GraphicsViewer.h
#ifndef GRAPHICSVIEWER_H
#define GRAPHICSVIEWER_H
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
class GraphicsViewer : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
GraphicsViewer(QWidget* parent = nullptr);
// QOpenGLWidget interface
protected:
void initializeGL();
void paintGL();
};
GraphicsViewer.cpp
#include "GraphicsViewer.h"
#include <QtOpenGL>
GraphicsViewer::GraphicsViewer(QWidget *parent) :
QOpenGLWidget (parent)
{
}
void GraphicsViewer::initializeGL()
{
initializeOpenGLFunctions();
}
void GraphicsViewer::paintGL()
{
glClearColor(1, 0, 0, 1);
}

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"

Q_PROPERTY not working properly in linux distro

i’m developing a clock application and I need to do it using Q_PROPERTY. The idea is to make all the clock control logic using C++ and deploy it in a QML GUI.
I got this working on a windows machine but when I run it on a linux distro in a development board I get sometimes undefined text (which are the exposed properties from C++).
The header file is:
#ifndef QCPPCLOCK_H
#define QCPPCLOCK_H
#include <QObject>
#include <QDebug>
#include <QString>
#include <QTime>
#ifdef __linux__
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#endif
class QcppClock : public QObject
{
Q_OBJECT
Q_PROPERTY(QString hours READ hours WRITE setHours NOTIFY hoursChanged)
Q_PROPERTY(QString minutes READ minutes WRITE setMinutes NOTIFY minutesChanged)
private:
QString actualHours;
QString actualMinutes;
QObject* rootObject;
QTime actualTime;
qint8 alarmHour;
qint8 alarmMinutes;
QString timeFormat;
bool alarmSet;
#ifdef __linux__
struct tm* ptm;
struct timeval tv;
#endif
public:
explicit QcppClock(QObject *parent = 0);
QString hours();
void setHours(QString);
QString minutes();
void setMinutes(QString);
public slots:
void qcppClock_vUpdateTextTime_slot(void);
signals:
void qcppClock_vTriggerAlarm_signal(void);
void hoursChanged(void);
void minutesChanged(void);
};
#endif // QCPPCLOCK_H
The .cpp file:
#include "qcppclock.h"
#include <QTimer>
#include <QtCore/qmath.h>
QcppClock::QcppClock(QObject *parent) :
QObject(parent)
{
QTimer* timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(qcppClock_vUpdateTextTime_slot()));
rootObject = parent;
actualTime = QTime::currentTime();
/* Initialize the format to 24 hours */
timeFormat = "24hours";
timer->start(1000);
#ifdef __linux__
gettimeofday (&tv, NULL);
ptm = localtime (&tv.tv_sec);
int hour = ptm->tm_hour;
//setHours(hour);
//actualHours = QString::number(hour);
int minutes = ptm->tm_min;
//setMinutes(minutes);
//actualMinutes = QString::number(minutes);
int seconds = ptm->tm_sec;
(void)actualTime.setHMS(hour , minutes, seconds);
#endif
}
QString QcppClock::hours()
{
return actualHours;
}
void QcppClock::setHours(QString newHours)
{
actualHours = newHours;
#ifdef __linux__
tv.tv_sec += 3600 * actualHours.toInt();
settimeofday(&tv, NULL);
#else
(void)actualTime.setHMS(actualHours.toInt() , actualMinutes.toInt(), actualTime.second());
#endif
emit hoursChanged();
}
QString QcppClock::minutes()
{
return actualMinutes;
}
void QcppClock::setMinutes(QString newMinutes)
{
actualMinutes = newMinutes;
#ifdef __linux__
tv.tv_sec += 60 * actualMinutes.toInt();
settimeofday(&tv, NULL);
#else
(void)actualTime.setHMS(actualHours.toInt() , actualMinutes.toInt(), actualTime.second());
#endif
emit minutesChanged();
}
void QcppClock::qcppClock_vUpdateTextTime_slot(void)
{
actualTime = actualTime.addSecs(1);
actualMinutes = QString::number(actualTime.minute());
emit minutesChanged();
actualHours = QString::number(actualTime.hour());
emit hoursChanged();
QString::number(actualTime.minute());
}
The main file which instantiates the clockctrl object is:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "qcpp_Clock/qcppclock.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QcppClock qcpp_Clock;
QQmlContext* context = engine.rootContext();
context->setContextProperty("clockCtrl", &qcpp_Clock);
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
return app.exec();
}
And the QML file using the exposed properties is:
import QtQuick 2.2
import QtQuick.Window 2.1
Window {
visible: true
width: 800
height: 480
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
Text {
property string prHours: clockCtrl.hours
property string prMinutes: clockCtrl.minutes
text: {
console.log(clockCtrl, clockCtrl.hours, clockCtrl.minutes);
return (prHours + " : " + prMinutes)
}
anchors.centerIn: parent
}
}
As you can see it’s a short and easy code, the problem is in QML when I try to make reference to the C++ exposed properties, i added a couple of consoles in order to see the result in the log and It works like a charm in windows, I never get these “undefined text” but in the development board with linux distro I get sometimes:
qml: QcppClock(0×7e8eeca8) 1 49
qml: QcppClock(0×7e8eeca8) undefined undefined
qml: QcppClock(0×7e8eeca8) 1 49
The first debug is the address of the c++ exposed object in C++, then, the Q_PROPERTY “hour” and the Q_PROPERTY “minutes”.
Thank you in advance.
Ramsés

failure to initialize multiple windows using qt

I've been struggling with the problem of initializing of multiple forms in Qt under Windows (the version is 5.0.1 but I don't reckon this to matter much). Long story short, my application contains of 2 forms the one of which is supposed to be called on clicking the button on the another one.
The code runs as follows:
1) main.cpp:
#include "main.h"
#include <QApplication>
FmNewWord fmNewWord;
MainWindow w;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
w.show();
return a.exec();
}
2) main.h:
#ifndef MAIN_H
#define MAIN_H
#include "mainwindow.h"
#include "fmnewword.h"
extern FmNewWord fmNewWord;
extern MainWindow w;
#endif // MAIN_H
3) mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "ui_mainwindow.h"
class MainWindow : public QMainWindow, private Ui::MainWindow
{
Q_OBJECT
signals:
void sgnl_new_word();
public:
explicit MainWindow(QWidget *parent = 0);
protected:
void changeEvent(QEvent *e);
private slots:
void on_commandLinkButton_clicked();
void on_miExit_triggered();
void on_miNewWord_triggered();
};
#endif // MAINWINDOW_H
4) mainwindow.cpp:
#include "main.h"
#include <Windows.h>
extern FmNewWord fmNewWord;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
setupUi(this);
}
void MainWindow::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
retranslateUi(this);
break;
default:
break;
}
}
void MainWindow::on_commandLinkButton_clicked()
{
MessageBox(0, 0, 0, 0);
}
void MainWindow::on_miExit_triggered()
{
this->close();
}
void MainWindow::on_miNewWord_triggered()
{
fmNewWord.show();
}
5) fmnewword.cpp:
#include "fmnewword.h"
FmNewWord::FmNewWord(QWidget *parent) :
QMainWindow(parent)
{
setupUi(this); /// here the app crashes with parent == NULL
}
void FmNewWord::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
retranslateUi(this);
break;
default:
break;
}
}
6) fmnewword.h:
#ifndef FMNEWWORD_H
#define FMNEWWORD_H
#include "ui_fmnewword.h"
class FmNewWord : public QMainWindow, private Ui::FmNewWord
{
Q_OBJECT
public:
explicit FmNewWord(QWidget *parent = 0);
protected:
void changeEvent(QEvent *e);
};
#endif // FMNEWWORD_H
The code keeps crashing during inititialization in fmnewword.cpp on the line shown. Could anybody point out the reason? Thanks.
First of all, QApplication must be created before any widgets.
Your code should look llike this:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
And that's how the second form must be created:
class FmNewWord;
class MainWindow : public QMainWindow, private Ui::MainWindow
{
Q_OBJECT
...
private slots:
void on_miNewWord_triggered();
private:
FmNewWord *fmNewWord;
};
void MainWindow::on_miNewWord_triggered()
{
fmNewWord = new FmNewWord;
fmNewWord->show();
}

Connecting signals and slots in a QTextEdit subclass?

I derived a class from QTextEdit and use it as a "logbook". I equipped it with a slot to receive log-messages.
class CLogbook : public QTextEdit
{
Q_OBJECT;
public:
void log(QString msg) {append(msg)};
public slots:
void recvLogSignal(const QString message)
{
append("hallo");
std::cout << "signal received.\n";
log(message);
}
};
another class then emits a signal like this:
// in the header
signals:
void logMessage(const QString);
// in the implementation
emit logMessage("qt is cute");
std::cout << "if you can read this the logMessage was emitted\n";
and also i connect the signal to the slot
connect(tableeditor, SIGNAL(logMessage(const QString)), logbook, SLOT(recvLogSignal(const QString)));
However the message is never shown in the "logbook". What am i missing here?
SOLVED: The connect method was called after emitting the signal :-(
It is hard to see exactly what is wrong with your implementation without a full example. Sometimes signals or slots will fail if an object goes out of scope if it isn't initialized on the heap.
Another way that it could fail is if your QApplication hasn't reached the exec() call.
I haven't experimented with using const in signal and slot calls, and I haven't seen it in any examples before, so that could be causing the problem; but it seems to work fine in the example below.
Working Example With a Derived Class of QTextEdit
Here is a simple example I put together that does some basic logging with a push button and a line edit.
Here is the header:
#ifndef WIDGET_H
#define WIDGET_H
#include <QtGui/QWidget>
//#include <QTextEdit>
#include "clogbook.h"
#include <QLineEdit>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget() {}
public slots:
void on_pushButton();
void on_lineEditReturn();
private:
CLogBook * text_edit_log;
QLineEdit * line_edit;
};
#endif // WIDGET_H
Here is the source:
#include "widget.h"
#include <QBoxLayout>
#include <QPushButton>
#include <QTimer>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QBoxLayout * box_layout = new QBoxLayout(QBoxLayout::TopToBottom);
text_edit_log = new CLogBook;
line_edit = new QLineEdit("Type Here and press Enter.");
QPushButton * push_button = new QPushButton("Click to Add To Log");
text_edit_log->setText("My Log Book");
box_layout->addWidget(text_edit_log);
box_layout->addWidget(line_edit);
box_layout->addWidget(push_button);
this->setLayout(box_layout);
QObject::connect(push_button, SIGNAL(clicked()), this, SLOT(on_pushButton()));
QObject::connect(line_edit, SIGNAL(returnPressed()), this, SLOT(on_lineEditReturn()));
}
void Widget::on_pushButton()
{
// text_edit_log->append("Push Button Logging Test");
text_edit_log->recvLogSignal("Push button test.");
}
void Widget::on_lineEditReturn()
{
// text_edit_log->append(line_edit->text());
text_edit_log->recvLogSignal(QString("LineEdit: ") + line_edit->text() );
line_edit->clear();
}
And here is the main:
#include <QtGui/QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
And here is the CLogBook class:
#ifndef CLOGBOOK_H
#define CLOGBOOK_H
#include <QTextEdit>
#include <iostream>
class CLogBook : public QTextEdit
{
Q_OBJECT
public:
explicit CLogBook(QWidget *parent = 0) : QTextEdit(parent) { }
void log (QString msg) { append(msg); }
public slots:
void recvLogSignal(const QString message)
{
append("hallo");
std::cout << "signal received.\n" << std::endl;
log(message);
}
};
#endif // CLOGBOOK_H

Resources