I have created a project and a basic app where there is a ui that pops up for users to enter data and then the data is uploaded to a firebase database. When I attempt to run the app the ui appears and i can enter in the data like in this image:
Here is my main.cpp:
#include "checkinapp.h"
#include "databasehandler.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
checkinapp w;
w.show();
DatabaseHandler dbhandler;
return a.exec();
}
The app gets stuck on w.show(). How can i make the submit button end w.show() and run the next line DatabaseHandler dbhandler
here is my checkinapp.h:
#ifndef CHECKINAPP_H
#define CHECKINAPP_H
#include <iostream>
#include <QMainWindow>
#include <QFile>
#include <QFileDialog>
#include <QTextStream>
#include <QMessageBox>
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
QT_BEGIN_NAMESPACE
namespace Ui { class checkinapp; }
QT_END_NAMESPACE
class checkinapp : public QMainWindow
{
Q_OBJECT
public:
checkinapp(QWidget *parent = nullptr);
~checkinapp();
private slots:
void on_happy_valueChanged(int value);
void on_hungry_valueChanged(int value);
void on_sleep_valueChanged(int value);
void on_stress_valueChanged(int value);
void on_male_toggled(bool checked);
void on_female_toggled(bool checked);
void on_other_toggled(bool checked);
void on_help_toggled(bool checked);
void on_pushButton_clicked();
private:
Ui::checkinapp *ui;
};
#endif // CHECKINAPP_H
checkinapp.cpp:
#include "checkinapp.h"
#include "ui_checkinapp.h"
#include "databasehandler.h"
#include "global_objects.hpp"
#include <QNetworkRequest>
#include <QDebug>
#include <QJsonDocument>
#include <QVariantMap>
#include <iostream>
using namespace std;
checkinapp::checkinapp(QWidget *parent)
: QMainWindow(parent),
ui(new Ui::checkinapp)
{
ui->setupUi(this);
}
checkinapp::~checkinapp()
{
if(help == 1)
{
//delete ui;
}
if(help == 1)
{
cout << "help";
}
}
void checkinapp::on_happy_valueChanged(int value)
{
happy = value;
}
void checkinapp::on_hungry_valueChanged(int value)
{
hungry = value;
}
void checkinapp::on_sleep_valueChanged(int value)
{
tired = value;
}
void checkinapp::on_stress_valueChanged(int value)
{
stressed = value;
}
void checkinapp::on_male_toggled(bool checked)
{
if(checked == true)
{
gender = 0;
}
}
void checkinapp::on_female_toggled(bool checked)
{
if(checked == true)
{
gender = 1;
}
}
void checkinapp::on_other_toggled(bool checked)
{
if(checked == true)
{
gender = 2;
}
}
void checkinapp::on_help_toggled(bool checked)
{
if(checked == true)
{
help = 1;
}
}
void checkinapp::on_pushButton_clicked()
{
submitted = true;
if(submitted==true)
{
cout <<submitted;
}
//delete ui;
}
databasehandler.h:
#ifndef DATABASEHANDLER_H
#define DATABASEHANDLER_H
#include <checkinapp.h>
#include <QObject>
#include <QWidget>
#include <QNetworkAccessManager>
#include <QNetworkReply>
class DatabaseHandler : public QObject
{
Q_OBJECT
public:
explicit DatabaseHandler(QObject *parent = nullptr);
~DatabaseHandler();
public slots:
void networkReplyReadyRead();
signals:
private:
QNetworkAccessManager * m_networkManager;
QNetworkReply * m_networkReply;
};
#endif // DATABASEHANDLER_H
databasehandler.cpp:
#include "checkinapp.h"
#include "databasehandler.h"
#include "global_objects.hpp"
#include <QNetworkRequest>
#include <QDebug>
#include <QJsonDocument>
#include <QVariantMap>
#include <iostream>
DatabaseHandler::DatabaseHandler(QObject *parent) : QObject(parent)
{
m_networkManager = new QNetworkAccessManager ( this );
QVariantMap newUser;
newUser[ "Stress" ] = QString::number(stressed);
newUser[ "Sleep" ] = QString::number(tired);
newUser[ "Hungry" ] = QString::number(hungry);
newUser[ "Happy" ] = QString::number(happy);
newUser[ "Grade" ] = QString::number(grade);
newUser[ "Date" ] = "1/10/21";
newUser[ "Gender" ] = QString::number(gender);
newUser[ "Aid" ] = QString::number(help);
QJsonDocument jsonDoc = QJsonDocument::fromVariant( newUser );
QNetworkRequest newUserRequest( QUrl( "url/User.json"));
newUserRequest.setHeader( QNetworkRequest::ContentTypeHeader, QString( "application/json" ));
m_networkManager->post( newUserRequest, jsonDoc.toJson() );
}
DatabaseHandler::~DatabaseHandler()
{
m_networkManager->deleteLater();
}
void DatabaseHandler::networkReplyReadyRead()
{
//qDebug() << m_networkReply->readAll();
}
Okay, I think you have some confusion. w.show() makes the window appear. That's it. Execution continues all the way to your a.exec().
What you need to do is have your window tell your DatabaseHandler when it's time to grab values and do an update. The Qt way is to set up a signal. I find those to kind of be a pain, so I use dependency injection. That is, I'd create the handler earlier in main but NOT have the constructor do all that. Make a method. Then pass a reference to the handler in the constructor of the window.
Then when the button is clicked, call a method on the handler to do its job. After that, you can close the app if you want.
Related
I can't get the qt preview pane to work. It's always black after I plug in the camera.
INFO:
Mac mini
OS: macOS m1, montery 12.3.1
Platform: Qt 6.3
Port: USB3.0
Img format: YUY2
Code snippets:
main.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsVideoItem>
#include <QCamera>
#include <QMediaCaptureSession>
#include <QMediaDevices>
#include <QCameraDevice>
#include <QList>
#include <QAudioInput>
#include <QCloseEvent>
#include <QPushButton>
#include <QImageCapture>
#include "opencv2/opencv.hpp"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
void showEvent(QShowEvent* event);
void closeEvent(QCloseEvent* event);
private:
Ui::MainWindow *ui;
QGraphicsView* pGraphyView;
QGraphicsScene* pGraphyScene;
QGraphicsVideoItem* pGraphyVideoItem;
QCamera* pCamera;
QMediaCaptureSession captureSession;
QAudioInput* pAudioInput;
QImageCapture* pImageCapture;
cv::Mat srcImage;
cv::Mat dstImage;
};
#endif // MAINWINDOW_H
main.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
//=====================================================================
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
pGraphyView = 0;
pGraphyScene = 0;
pGraphyVideoItem = 0;
pCamera = 0;
}
//=====================================================================
MainWindow::~MainWindow()
{
delete ui;
}
//=====================================================================
void MainWindow::showEvent(QShowEvent* event)
{
pAudioInput = new QAudioInput;
captureSession.setAudioInput(pAudioInput);
QStringList str_list;
QString str_id;
QString str_vid;
QString str_pid;
const QList<QCameraDevice> cameras = QMediaDevices::videoInputs();
qDebug() << "camera count = " << cameras.size();
for (const QCameraDevice &cameraDevice : cameras)
{
str_id = cameraDevice.id();
str_vid = str_id.mid(9,4);
str_pid = str_id.right(4);
qDebug() << "id = " << str_id;
qDebug() << "vid = 0x" << str_vid;
qDebug() << "pid = 0x" << str_pid;
if(str_vid == "a168")
{
pCamera = new QCamera(cameraDevice);
captureSession.setCamera(pCamera);
pGraphyScene = new QGraphicsScene(0,0,640,480);
pGraphyView = new QGraphicsView(this);
pGraphyView->setScene(pGraphyScene);
this->setCentralWidget((QWidget*)pGraphyView);
pGraphyVideoItem = new QGraphicsVideoItem;
pGraphyVideoItem->setSize(QSizeF(640,480));
pGraphyVideoItem->setPos(0,0);
pGraphyScene->addItem(pGraphyVideoItem);
captureSession.setVideoOutput(pGraphyVideoItem);
pCamera->start(); // live play.
break;
}
}
}
//=====================================================================
void MainWindow::closeEvent(QCloseEvent* event)
{
if(pAudioInput)
{
delete pAudioInput;
pAudioInput = 0;
}
if(pGraphyVideoItem)
{
delete pGraphyVideoItem;
pGraphyVideoItem = 0;
}
if(pGraphyScene)
{
delete pGraphyScene;
pGraphyScene = 0;
}
if(pGraphyView)
{
delete pGraphyView;
pGraphyView = 0;
}
event->accept();
}
I tried using macOS' facetime to check if the camera itself is functionable, and it did. The facetime live play smoothly.
I guess it's something related to Qt 6.3.
Having a problem with main window crashing on close, but only if I open the window normal size (not filling the screen) and then maximize it and close the window. If I open it normal size and close it, no problem. This project includes a tableview, tableModel and a ProxyModel. While debugging, it seems to be crashing on this statement in the proxy model header function:
return sourceModel()->headerData(section, orientation, role);
I'm assuming I am missing something in my main constructor based on what I've researched, but I'm not seeing it.
Main Window:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QString>
#include "XMLFile.h"
#include "XMLReader.h"
#include "XMLWriter.h"
#include <QFile>
#include <QMainWindow>
#include <QTableWidget>
#include <QStringList>
#include <QHeaderView>
#include <QAction>
#include <QStandardItemModel>
#include <QTableView>
#include <QSortFilterProxyModel>
#include "TableModel.h"
#include "ProxyModel.h"
#include <QItemSelectionModel>
#include "CustomTableView.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
QWidget *centralWidget;
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
const QString filename;
public slots:
void ReceiveMessage( const QString &message );
signals:
void readXmlFile( const QString &fileName );
void getXmlTableData();
void setFilter( QString );
private slots:
void on_actionOpen_triggered();
void on_actionFind_triggered();
void on_pushButton_clicked();
void on_tableView_activated(const QModelIndex &index);
void on_actionExport_XML_triggered();
void on_actionExit_triggered();
private:
Ui::MainWindow *ui;
QString xmlFileName;
QFile file;
XMLReader xmlReader;
XMLWriter xmlWriter;
QVector<QString> xmlArray;
QString filter = "";
CustomTableView *tableView;
TableModel mTableModel;
ProxyModel* proxyModel;
QString accountValue;
QString deptValue;
QString yearValue;
QString filterText;
void createItems();
void createConnections();
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QString>
#include <QDebug>
#include <QMessageBox>
#include <QFile>
#include <QFileDialog>
#include <QApplication>
#include "XMLReader.h"
#include "XMLWriter.h"
#include "XMLFile.h"
#include <QInputDialog>
#include <QMenu>
#include <QModelIndexList>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, xmlReader( filename )
, xmlWriter( filename, &mTableModel )
//, tableView( NULL )
//, proxyModel( NULL )
//, m_xmlView(NULL)
{
ui->setupUi(this);
connect(&xmlReader, SIGNAL(SendMessage(const QString)), this, SLOT(ReceiveMessage(const QString)));
/* Setup tableview */
tableView = new CustomTableView(this);
ui->verticalLayout->addWidget(tableView);
tableView->setSortingEnabled(true);
/* Table Model Setup */
proxyModel = new ProxyModel(this);
proxyModel->setSourceModel(&mTableModel);
createConnections();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::ReceiveMessage(const QString &message)
{
QMessageBox::warning(this, "Warning", "Cannot open file : " + message);
}
void MainWindow::on_actionOpen_triggered()
{
QString filename = QFileDialog::getOpenFileName((this),"Open file");
xmlReader.readFile(filename);
setWindowTitle(filename);
createItems();
}
void MainWindow::createItems()
{
xmlArray = xmlReader.getXmlData();
int tableSize = xmlArray.size();
QStringList strList;
QString strSplit = "";
QVector<TableItem> rows;
/* Split into individual items, add as row to tableItem array.*/
/* Insert each tableItem array into the table model. */
for( int row = 0; row < tableSize; row++ )
{
TableItem newRow;
strSplit = xmlArray[row];
strList = strSplit.split("|");
for( int k = 0; k < strList.length(); k++)
{
newRow.setData(k, strList[k] );
}
rows << newRow;
}
mTableModel.initModel( rows );
QAbstractItemModel* model = nullptr;
model = proxyModel;
tableView->setModel( model );
tableView->setColumnHidden(0, true);
}
void MainWindow::createConnections()
{
QObject::connect(ui->lineEdit, SIGNAL(textChanged(QString)), proxyModel, SLOT(setAccount(QString)));
QObject::connect(ui->lineEdit_2, SIGNAL(textChanged(QString)), proxyModel, SLOT(setDept(QString)));
QObject::connect(ui->lineEdit_3, SIGNAL(textChanged(QString)), proxyModel, SLOT(setYear(QString)));
QObject::connect(this, SIGNAL(setFilter(QString)), proxyModel, SLOT(setSearchFilter(QString)));
}
void MainWindow::on_actionFind_triggered()
{
/* Open find string dialog */
bool ok;
QString filterText = QInputDialog::getText(this, tr("Find"),
tr("Search for string:"), QLineEdit::Normal,"", &ok);
setFilter( filterText );
}
void MainWindow::on_pushButton_clicked()
{
/* Clear filter values */
ui->lineEdit->setText("");
ui->lineEdit_2->setText("");
ui->lineEdit_3->setText("");
setFilter("");
}
void MainWindow::on_tableView_activated(const QModelIndex &index)
{
}
void MainWindow::on_actionExport_XML_triggered()
{
/* Open save file dialog, call xmlWriter */
QString filename = QFileDialog::getSaveFileName(this, tr("Save XML File"), ".", tr("XML files (*.xml)"));
xmlWriter.WriteFile(filename);
}
void MainWindow::on_actionExit_triggered()
{
QApplication::quit();
}
WORKING CODE: MainWindow.cpp
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, xmlReader( filename )
{
ui->setupUi(this);
connect(&xmlReader, SIGNAL(SendMessage(const QString)), this, SLOT(ReceiveMessage(const QString)));
/* Setup tableview */
tableView = new CustomTableView(this);
ui->verticalLayout->addWidget(tableView);
tableView->setSortingEnabled(true);
/* Table Model Setup */
proxyModel = new ProxyModel(this);
proxyModel->setSourceModel(&mTableModel);
createConnections();
}
MainWindow::~MainWindow()
{
delete proxyModel; /* Newly added */
delete tableView; /* Newly added */
delete ui;
}
I can upload more source code if needed. Thanks for any insight here.
-d
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I know this question as been multiple times . I have browsed and trying for 5 days to link my C++ signal to a QML slot via Connections in QML . Here is my code at the moment and I don't understand why I always get :Cannot assign to non-existent property "ondashsetupChanged"
Please tell me what i am doing wrong ? The complete code is here :
https://github.com/BastianGschrey/PowerTune/tree/Simplification
Here is my code:
my main.cpp :
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QtQml>
#include "connect.h"
int main(int argc, char *argv[])
{
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QApplication app(argc, argv);
app.setOrganizationName("Power-Tune");
app.setOrganizationDomain("power-tune.org");
app.setApplicationName("PowerTune");
QQmlApplicationEngine engine;
qmlRegisterType<Connect>("com.powertune", 1, 0, "ConnectObject");
engine.rootContext()->setContextProperty("Connect", new Connect(&engine));
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
connect.cpp :
#include "datalogger.h"
#include "connect.h"
#include "calculations.h"
#include "sensors.h"
#include "AdaptronicSelect.h"
#include "AdaptronicCAN.h"
#include "Apexi.h"
#include "HaltechCAN.h"
#include "Nissanconsult.h"
#include "obd.h"
#include "AdaptronicCAN.h"
#include "HaltechCAN.h"
#include "Apexi.h"
#include "AdaptronicSelect.h"
#include "dashboard.h"
#include "serialport.h"
#include "appsettings.h"
#include "gopro.h"
#include "gps.h"
#include <QDebug>
#include <QTime>
#include <QTimer>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QQmlContext>
#include <QQmlApplicationEngine>
#include <QFile>
#include <QFileInfo>
#include <QTextStream>
#include <QByteArrayMatcher>
#include <QProcess>
int ecu; //0=apex, 1=adaptronic;2= OBD; 3= Dicktator ECU
int logging; // 0 Logging off , 1 Logging to file
int connectclicked =0;
QByteArray checksumhex;
QByteArray recvchecksumhex;
Connect::Connect(QObject *parent) :
QObject(parent),
m_serialport(Q_NULLPTR),
m_dashBoard(Q_NULLPTR),
m_gopro(Q_NULLPTR),
m_gps(Q_NULLPTR),
m_adaptronicselect(Q_NULLPTR),
m_apexi(Q_NULLPTR),
m_nissanconsult(Q_NULLPTR),
m_OBD(Q_NULLPTR),
m_sensors(Q_NULLPTR),
m_haltechCANV2(Q_NULLPTR),
m_adaptronicCAN(Q_NULLPTR),
m_datalogger(Q_NULLPTR),
m_calculations(Q_NULLPTR)
{
getPorts();
m_dashBoard = new DashBoard(this);
m_appSettings = new AppSettings(this);
m_gopro = new GoPro(this);
m_gps = new GPS(m_dashBoard, this);
m_adaptronicselect= new AdaptronicSelect(m_dashBoard, this);
m_apexi= new Apexi(m_dashBoard, this);
m_nissanconsult = new Nissanconsult(m_dashBoard, this);
m_OBD = new OBD(m_dashBoard, this);
m_sensors = new Sensors(m_dashBoard, this);
m_haltechCANV2 = new HaltechCAN(m_dashBoard, this);
m_adaptronicCAN = new AdaptronicCAN(m_dashBoard, this);
m_datalogger = new datalogger(m_dashBoard, this);
m_calculations = new calculations(m_dashBoard, this);
QQmlApplicationEngine *engine = dynamic_cast<QQmlApplicationEngine*>( parent );
if (engine == Q_NULLPTR)
return;
engine->rootContext()->setContextProperty("Dashboard", m_dashBoard);
engine->rootContext()->setContextProperty("AppSettings", m_appSettings);
engine->rootContext()->setContextProperty("GoPro", m_gopro);
engine->rootContext()->setContextProperty("GPS", m_gps);
engine->rootContext()->setContextProperty("Nissanconsult",m_nissanconsult);
engine->rootContext()->setContextProperty("Sens", m_sensors);
engine->rootContext()->setContextProperty("Logger", m_datalogger);
}
Connect::~Connect()
{
}
void Connect::checkifraspberrypi()
{
QString path = "/sys/class/backlight/rpi_backlight/brightness";
if (QFileInfo::exists(path))
{
m_dashBoard->setscreen(true);
}
else
{
m_dashBoard->setscreen(false);
}
}
void Connect::readdashsetup()
{
qDebug()<<"c++ file read";
QString path = "UserDash.txt";// this is just for testing
QFile inputFile(path);
if (inputFile.open(QIODevice::ReadOnly))
{
QTextStream in(&inputFile);
while (!in.atEnd())
{
QString line = in.readLine();
QStringList list = line.split(QRegExp("\\,"));
m_dashBoard->setdashsetup(list);
qDebug()<< list;
}
inputFile.close();
}
}
void Connect::setSreenbrightness(const int &brightness)
{
//This works only on raspberry pi
QFile f("/sys/class/backlight/rpi_backlight/brightness");
//f.close();
f.open(QIODevice::WriteOnly | QIODevice::Truncate);
QTextStream out(&f);
out << brightness;
//qDebug() << brightness;
f.close();
}
void Connect::setUnits(const int &units)
{
switch (units)
{
case 0:
m_dashBoard->setunits("metric");
break;
case 1:
m_dashBoard->setunits("imperial");
break;
default:
break;
}
}
void Connect::setWeight(const int &weight)
{
m_dashBoard->setWeight(weight);
qDebug() << "weight" << m_dashBoard->Weight();
}
void Connect::getPorts()
{
QStringList PortList;
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
PortList.append(info.portName());
}
setPortsNames(PortList);
// Check available ports every 1000 ms
QTimer::singleShot(1000, this, SLOT(getPorts()));
}
//function for flushing all Connect buffers
void Connect::clear() const
{
// m_Connectport->clear();
}
//function to open Connect port
void Connect::openConnection(const QString &portName, const int &ecuSelect)
{
ecu = ecuSelect;
//Apexi
if (ecuSelect == 0)
{
m_apexi->openConnection(portName);
}
//Adaptronic
if (ecuSelect == 1)
{
m_adaptronicselect->openConnection(portName);
}
//OBD
if (ecuSelect == 2)
{
m_OBD->openConnection(portName);
}
//Nissan Consult
if (ecuSelect == 3)
{
m_nissanconsult->LiveReqMsg(1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
m_nissanconsult->openConnection(portName);
}
//Adaptronic ModularCAN protocol
if (ecuSelect == 5)
{
m_adaptronicCAN->openCAN();
}
//Haltech V2 CAN protocol
if (ecuSelect == 6)
{
m_haltechCANV2->openCAN();
}
}
void Connect::closeConnection()
{
//Apexi
if (ecu == 0)
{
m_apexi->closeConnection();
}
//Adaptronic Select
if (ecu == 1)
{
m_adaptronicselect->closeConnection();
}
//OBD
if (ecu == 2)
{
m_OBD->closeConnection();
}
//Nissan Consult
if (ecu == 3)
{
m_nissanconsult->closeConnection();
}
//Adaptronic ModularCAN protocol
if (ecu == 5)
{
m_adaptronicCAN->closeConnection();
}
//Haltech V2 CAN protocol
if (ecu == 6)
{
m_haltechCANV2->closeConnection();
}
}
void Connect::update()
{
m_dashBoard->setSerialStat("Update started");
QProcess *process = new QProcess(this);
connect(process , SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(updatefinished(int, QProcess::ExitStatus)));
process->start("/home/pi/updatePowerTune.sh");
process->waitForFinished(6000000); // 10 minutes time before timeout
}
void Connect::updatefinished(int exitCode, QProcess::ExitStatus exitStatus)
{
qDebug() << "code" <<exitCode;
qDebug() << "status" <<exitStatus;
QString fileName = "/home/pi/build/PowertuneQMLGui";
QFile file(fileName);
if(QFileInfo::exists(fileName))
{
m_dashBoard->setSerialStat("Update Successful");
file.close();
}
else
{
m_dashBoard->setSerialStat("Update Unsuccessful");
}
}
connect.h
#ifndef CONNECT_H
#define CONNECT_H
#include <QtSerialPort/QSerialPort>
#include <QObject>
#include <QModbusDataUnit>
#include <QTimer>
#include <QProcess>
#include "calculations.h"
class SerialPort;
class Sensors;
class DashBoard;
class AdaptronicCAN;
class AdaptronicSelect;
class Apexi;
class HaltechCAN;
class Nissanconsult;
class OBD;
class datalogger;
class calculations;
class AppSettings;
class GoPro;
class GPS;
class OBD;
class Connect : public QObject
{
Q_OBJECT
Q_PROPERTY(QStringList portsNames READ portsNames WRITE setPortsNames NOTIFY sig_portsNamesChanged)
public:
~Connect();
explicit Connect(QObject *parent = 0);
Q_INVOKABLE void checkifraspberrypi();
Q_INVOKABLE void readdashsetup();
Q_INVOKABLE void setSreenbrightness(const int &brightness);
Q_INVOKABLE void setUnits(const int &units);
Q_INVOKABLE void setWeight(const int &weight);
Q_INVOKABLE void clear() const;
Q_INVOKABLE void openConnection(const QString &portName, const int &ecuSelect);
Q_INVOKABLE void closeConnection();
Q_INVOKABLE void update();
public:
QStringList portsNames() const { return m_portsNames; }
private:
SerialPort *m_serialport;
DashBoard *m_dashBoard;
AppSettings *m_appSettings;
GoPro *m_gopro;
GPS *m_gps;
AdaptronicSelect *m_adaptronicselect;
Apexi *m_apexi;
Nissanconsult* m_nissanconsult;
OBD* m_OBD;
Sensors *m_sensors;
HaltechCAN *m_haltechCANV2;
AdaptronicCAN *m_adaptronicCAN;
datalogger *m_datalogger;
calculations *m_calculations;
QStringList m_portsNames;
QStringList *m_ecuList;
QThread* CALCThread;
QProcess process;
signals:
void sig_portsNamesChanged(QStringList portsNames);
public slots:
void updatefinished(int exitCode, QProcess::ExitStatus exitStatus);
void getPorts();
void setPortsNames(QStringList portsNames)
{
if (m_portsNames == portsNames)
return;
m_portsNames = portsNames;
emit sig_portsNamesChanged(portsNames);
}
};
#endif // CONNECT_H
dashbboard.cpp
#include <dashboard.h>
#include <QStringList>
#include <QDebug>
DashBoard::DashBoard(QObject *parent)
: QObject(parent)
{
}
void DashBoard::setdashsetup(const QStringList &dashsetup)
{
if (m_dashsetup == dashsetup)
return;
m_dashsetup = dashsetup;
emit dashsetupChanged(dashsetup);
}
//User Dashboard Stringlist
QStringList DashBoard::dashsetup() const { return m_dashsetup; }
dashboard.h
#ifndef DASHBOARD_H
#define DASHBOARD_H
#include <QStringList>
#include <QObject>
class DashBoard : public QObject
{
Q_OBJECT
//User Dashboard Stringlist dashsetup
Q_PROPERTY(QStringList dashsetup READ dashsetup WRITE setdashsetup NOTIFY dashsetupChanged)
public:
DashBoard(QObject *parent = 0);
//User Dashboard Stringlist
QStringList dashsetup() const;
signals:
QStringList m_dashsetup;
};
#endif // DASHBOARD_H
main.qml:
import QtQuick 2.8
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.1
import com.powertune 1.0
ApplicationWindow {
visible: true
width: 800
height: 480
minimumWidth: 800
minimumHeight: 480
title: qsTr("PowerTune ") + Dashboard.Platform + " Beta 24"
// visibility: "FullScreen"
color: "black"
Connections{
target: Dashboard
ondashsetupChanged: console.log("Dashboard has changed")
}
Item {
id: name
Component.onCompleted: Connect.checkifraspberrypi()
}
SwipeView {
id: view
currentIndex: 0
anchors.fill: parent
Loader {
id: firstPageLoader
source: ""
}
Loader {
id: secondPageLoader
source: ""
}
Loader {
id: thirdPageLoader
source: ""
}
Loader {
id: fourthPageLoader
source: ""
}
Item {
id:lastPage
SerialSettings{}
}
}
PageIndicator {
id: indicator
count: view.count
currentIndex: view.currentIndex
anchors.bottom: view.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
}
The first letter of the property name is always capitalised in signal handlers:
onDashsetupChanged: console.log("Dashboard has changed")
Property Change Signal Handlers explains this:
A signal is automatically emitted when the value of a QML property changes. This type of signal is a property change signal and signal handlers for these signals are written in the form onChanged where is the name of the property, with the first letter capitalized.
I don't know how to implement the managing of the escape key to quit the program. I don't know either where to put it in my code, because if I put it in a method, how can it quit anywhere?
This is my actual code :
#include <iostream>
#include <QApplication>
#include <QPushButton>
#include <QLineEdit>
#include <QFormLayout>
#include <QDebug>
#include "LibQt.hpp"
LibQt::LibQt() : QWidget()
{
this->size_x = 500;
this->size_y = 500;
QWidget::setWindowTitle("The Plazza");
setFixedSize(this->size_x, this->size_y);
manageOrder();
}
LibQt::~LibQt()
{
}
void LibQt::manageOrder()
{
this->testline = new QLineEdit;
this->m_button = new QPushButton("Send Order");
QFormLayout *converLayout = new QFormLayout;
this->m_button->setCursor(Qt::PointingHandCursor);
this->m_button->setFont(QFont("Comic Sans MS", 14));
converLayout->addRow("Order : ", this->testline);
converLayout->addWidget(this->m_button);
this->setLayout(converLayout);
QObject::connect(m_button, SIGNAL(clicked()), this, SLOT(ClearAndGetTxt()));
}
std::string LibQt::ClearAndGetTxt()
{
QString txt = this->testline->text();
this->usertxt = txt.toStdString();
std::cout << this->usertxt << std::endl;
this->testline->clear();
return (this->usertxt);
}
std::string LibQt::getUsertxt()
{
return (this->usertxt);
}
and this is my .hpp
#ifndef _LIBQT_HPP_
#define _LIBQT_HPP_
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QKeyEvent>
#include <QCheckBox>
#include <QPlainTextEdit>
class LibQt : public QWidget
{
Q_OBJECT
public:
LibQt();
~LibQt();
void manageOrder();
std::string getUsertxt();
public slots:
std::string ClearAndGetTxt();
protected:
int size_x;
int size_y;
QPushButton *m_button;
QLineEdit *testline;
std::string usertxt;
};
#endif /* _LIBQT_HPP_ */
You need to override the method void QWidget::keyPressEvent(QKeyEvent *event). It will look like this for you :
void LibQt::keyPressEvent(QKeyEvent* event)
{
if(event->key() == Qt::Key_Escape)
{
QCoreApplication::quit();
}
else
QWidget::keyPressEvent(event)
}
I know you solved this issue, and my solution is in Python, but other people may find this useful. Essentially, you can implement this feature as an action:
w = LibQt() # QWidget().
escape = QAction('Escape', w)
escape.setShortcut(QKeySequence('Esc'))
escape.setShortcutContext(Qt.WidgetWithChildrenShortcut) # acts as an event filter.
escape.triggered.connect(w.close)
w.addAction(escape)
Obviously, with first line removed, this code may be added to class constructor.
So, after I make my QJsonModel, load the data, and set the treeView model, it will load the data normally into the treeView. Although, when I do this after a network request has been finished (serviceRequestFinished(QNetworkReply* reply)), it just doesn't woek. I can qDebug the Json data that is passed, but when it comes down to the Json loading and the model setting. It just fails to finish. Also, for some reason it won't set the Json from the network request, but if I just set it to set the json from a separate button, the json get added successfully. So that means that the Json is formatted correctly. The QJsonModel & QJsonItem are external classes not provided with Qt, that located here.
Here is my code:
Mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QModelIndex>
#include <QItemSelection>
#include <QFile>
#include <QFileInfo>
#include <QList>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QStringList>
#include <QTimer>
#include <QUrl>
#include <QTreeWidgetItem>
#include <QJsonDocument>
#include <QJsonObject>
#include "qjsonmodel.h"
#include <QClipboard>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
void setJson(QString json);
void getPlaylistList(QString accessToken);
QString disableStreams();
void appendEditValues(int currentRow);
void addVectorItems();
void streamCheck();
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_radioButtonNoStream_clicked()
{
streamCheck();
}
void on_radioButtonTwitchStream_clicked()
{
streamCheck();
}
void on_radioButtonYTStream_clicked()
{
streamCheck();
}
void on_pushButtonAddVid_clicked();
void on_pushButtonApplyAddVid_clicked();
void on_pushButtonDeleteSelection_clicked();
void on_pushButtonApplyAll_clicked();
public slots:
void serviceRequestFinished(QNetworkReply* reply);
void connectAPI(QString code);
signals:
void authenticate(QString accessCode);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
Mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "authdialog.h"
#include <qDebug>
#include <QVector>
#include <QMessageBox>
#include <QStandardItemModel>
#include <QFile>
#include <QUrlQuery>
int val = 0;
int selected;
QVector<QString> vidTitles;
QVector<QString> vidUrls;
QVector<int> vidNumber;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
streamCheck();
ui->groupBoxEditVideo->setEnabled(false);
connect(this, SIGNAL(authenticate(QString)), SLOT(connectAPI(QString)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::streamCheck()
{
if (ui->radioButtonNoStream->isChecked())
{
ui->groupBoxStreamSetup->setEnabled(false);
ui->groupBoxStreamSetup->setTitle("No Stream Selected!");
}
else if (ui->radioButtonTwitchStream->isChecked())
{
ui->groupBoxStreamSetup->setEnabled(true);
ui->groupBoxStreamSetup->setTitle("Twitch Setup");
}
else if (ui->radioButtonYTStream->isChecked())
{
ui->groupBoxStreamSetup->setEnabled(true);
ui->groupBoxStreamSetup->setTitle("YouTube Stream Setup");
}
}
void MainWindow::on_pushButtonAddVid_clicked()
{
AuthDialog *auth = new AuthDialog(this);
auth->setModal(true);
auth->exec();
delete auth;
}
void MainWindow::setJson(QString json)
{
qDebug() << json;
QJsonModel * model = new QJsonModel;
model->loadJson(json.toUtf8());
ui->treeView->setModel(model);
delete model;
}
void MainWindow::getPlaylistList(QString accessToken)
{
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*)));
//
QNetworkRequest request(QUrl("https://www.googleapis.com/youtube/v3/search?part=snippet&forMine=true&order=viewCount&type=video&access_token=" + accessToken));
networkManager->get(request);
}
QString MainWindow::disableStreams()
{
QString line = "";
QString test = "";
QFile file;
file.setFileName("C:/WampStack/apache2/htdocs/index.html");
file.open(QIODevice::ReadWrite);
QTextStream in(&file);
while(!in.atEnd())
{
line += in.readAll();
}
if (line.contains("<!--t-->") && !line.contains("<!--y-->"))
{
//Twitch Stream is on, must turn it off
test = line.replace("<!--t-->", "<!--t");
test = test.replace("><!--tt-->", ">tt-->");
return test;
}
else if (line.contains("<!--y-->") && !line.contains("<!--t-->"))
{
//YouTube Stream is on, must turn it off
test = line.replace("<!--y-->", "<!--y");
test = test.replace("><!--yy-->", ">yy-->");
return test;
}
else if (line.contains("<!--y-->") && line.contains("<!--t-->"))
{
test = line.replace("<!--y-->", "<!--y");
test = test.replace("><!--yy-->", ">yy-->");
test = test.replace("<!--t-->", "<!--t");
test = test.replace("><!--tt-->", ">tt-->");
return test;
}
else
{
return line;
}
file.close();
return line;
}
void MainWindow::connectAPI(QString code)
{
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*)));
QUrlQuery postData;
postData.addQueryItem("code", code);
postData.addQueryItem("client_id", "CLIENT-ID");
postData.addQueryItem("client_secret", "CLIENT-SECRET");
postData.addQueryItem("redirect_uri", "REDIRECT-URI");
postData.addQueryItem("grant_type", "authorization_code");
QNetworkRequest request(QUrl("https://accounts.google.com/o/oauth2/token"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
networkManager->post(request, postData.toString(QUrl::FullyEncoded).toUtf8());
}
void MainWindow::appendEditValues(int currentRow)
{
}
void MainWindow::addVectorItems()
{
}
void MainWindow::on_pushButtonApplyAddVid_clicked()
{
}
void MainWindow::on_pushButtonDeleteSelection_clicked()
{
QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, "Are you sure?", "Do you want to permanently delete this entry?", QMessageBox::Yes|QMessageBox::No);
if (reply == QMessageBox::Yes)
{
}
addVectorItems();
}
void MainWindow::on_pushButtonApplyAll_clicked()
{
QString line = disableStreams();
QFile::remove("C:/WampStack/apache2/htdocs/index.html");
QFile file;
file.setFileName("C:/WampStack/apache2/htdocs/index.html");
file.open(QIODevice::ReadWrite);
//Start code for streaming
if (ui->radioButtonTwitchStream->isChecked() && line.contains("<!--t") && line.contains(">tt-->") && !line.contains("<!--t-->") && !line.contains("<!--tt-->"))
{
QString test = line.replace("<!--t", "<!--t-->");
test = line.replace(">tt-->", "><!--tt-->");
QTextStream stream( &file );
stream << test;
}
else if (ui->radioButtonYTStream->isChecked() && line.contains("<!--y") && line.contains(">yy-->") && !line.contains("<!--y-->") && !line.contains("<!--yy-->"))
{
QString test = line.replace("<!--y", "<!--y-->");
test = test.replace(">yy-->", "><!--yy-->");
QTextStream stream( &file );
stream << test;
}
else if (ui->radioButtonNoStream->isChecked())
{
QTextStream stream(&file);
stream << line;
}
//End code for streaming
file.close();
}
void MainWindow::serviceRequestFinished(QNetworkReply* reply)
{
QByteArray json = reply->readAll();
QString output = QString::fromUtf8(json);
QJsonDocument settdoc = QJsonDocument::fromJson(output.toUtf8());
QJsonObject sett2 = settdoc.object();
if (val == 0)
{
val++;
getPlaylistList(sett2.value(QString("access_token")).toString());
}
else if (val == 1)
{
setJson(output.toUtf8());
}
}
Main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
QJsonModel only works if the the JSON's root element is an object (see the bug report on github.com). I guess your JSON's root is an array.