QT5 C ++信号到QML插槽无法正常工作

时间:2018-03-30 17:43:00

标签: c++ qt qml

我多次知道这个问题。我已经浏览并尝试了5天,通过QML中的Connections将我的C ++信号链接到QML插槽。这是我目前的代码,我不明白为什么我总是得到:不能分配给不存在的属性“ondashsetupChanged” 请告诉我我做错了什么?完整的代码在这里: https://github.com/BastianGschrey/PowerTune/tree/Simplification

这是我的代码:

我的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
}
}

1 个答案:

答案 0 :(得分:1)

属性名称的第一个字母始终在信号处理程序中大写:

onDashsetupChanged: console.log("Dashboard has changed")

Property Change Signal Handlers解释了这一点:

  

当QML属性的值发生变化时,会自动发出信号。这种类型的信号是属性变化信号,这些信号的信号处理程序以onChanged的形式写入,其中是属性的名称,首字母大写。