我多次知道这个问题。我已经浏览并尝试了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
}
}
答案 0 :(得分:1)
属性名称的第一个字母始终在信号处理程序中大写:
onDashsetupChanged: console.log("Dashboard has changed")
Property Change Signal Handlers解释了这一点:
当QML属性的值发生变化时,会自动发出信号。这种类型的信号是属性变化信号,这些信号的信号处理程序以onChanged的形式写入,其中是属性的名称,首字母大写。