Zugriff von Instanzvariablen über std::bind?
-
Genua so meinte ich es mit dem Konstruktor. Jetzt fehlen nur noch passende Member in der Klasse (was ich mit meinem Kommentar im letzten Code meinte):
class PaintEICAS : public QWidget { // ... private: const Engine *engineL; const Engine *engineR; }
(
const
wenn du nur lesend darauf zugreifst - was für Viewklassen am sinnvollsten ist!)Und diese initialisierst du im Konstruktor:
PaintEICAS::PaintEICAS(QWidget* parent, const Engine* engineL, const Engine* engineR) : QWidget(parent), engineL(engineL), engineR(engineR) { }
(den
parent
würde ich immer als erstes übergeben, so daß du eine einheitliche Schnittstelle für alle deine Qt-Klassen hast)
Falls dich stört (bzw. unleserlich/unverständlich ist), daß sowohl Konstruktorparameter als auch Member gleich heißen, so kannst du selbstverständlich auch dies ändern).Und dann greifst du einfach auf die Membervariablen z.B. in der
paintEvent
-Funktion zu:int spanAngle2 = engineL->GetN1() * 16;
(also paßt jetzt -fast- dein vorheriger Kommentar ;- )
Wenn du mehrere Qt-Klassen (Views) hast, die diese
Engine
-Daten benötigen, so solltest du besser dafür eine eigene Struktur/Klasse anlegen, welche du dann als ein Parameter übergibst - gerade wenn evtl. auch noch andere Daten benötigt werden.Außerdem könntest du dir dann überlegen, ob du nicht sogar MVVM einsetzen möchtest: Model/View Programming | Qt Widgets 6.2.1.
PS: Membernamen wie
n
(inEngine
) solltest du vermeiden, da sie nicht sehr aussagekräftig sind (und bei Benutzung im Code mit lokalen Variablen verwechselt werden könnten).
Ich nehme mal an, daß (zumindestens) für dichN1
,N2
sinnvolle Namen sind, ansonsten gilt gleiches auch hier.
-
Vielen Dank an alle, insbesondere hat Th69 sehr ausführlich geantwortet, danke schön!
(den
parent
würde ich immer als erstes übergeben, so daß du eine einheitliche Schnittstelle für alle deine Qt-Klassen hast)Da hat der Compiler gemeckert -> der QWidget* parent solle nach hinten, warum auch immer...
Falls dich stört (bzw. unleserlich/unverständlich ist), daß sowohl Konstruktorparameter als auch Member gleich heißen, so kannst du selbstverständlich auch dies ändern).
Danke, weiß ich
-
@stefanpc81
Was ich meinte wäre so:class PaintEICAS : public QWidget { public: // ... void SetN1Values(int left, right) { engineL_N1 = left; engineR_N1 = right; } private: // ... int engineL_N1 = 0; int engineR_N1 = 0; };
SetN1Values
muss dann immer aufgerufen werden wenn sich einer der N1 Werte geändert haben könnte. Falls das in der Klasse passiert die auch dieengineL
undengineR
Member hat, kannst du das einfach so aufrufen:otherClass.SetN1Values(engineL->GetN1(), engineR->GetN1());
Und in
PaintEICAS::paintEvent
verwendest du dann einfach die WerteengineL_N1
undengineR_N1
.
-
@hustbaer
Danke für den Vorschlag, aber später kommen noch die anderen Werte dran:
engineL/R->
N2,
N1_soll,
N2_soll
Die sollen aber nicht alle über die gleiche Klasse aufgerufen werden. Da ist es mit meiner Aufteilung in zwei Engine-Instanzen einfacher (mMn).
-
@stefanpc81 sagte in Zugriff von Instanzvariablen über std::bind?:
(den
parent
würde ich immer als erstes übergeben, so daß du eine einheitliche Schnittstelle für alle deine Qt-Klassen hast)Da hat der Compiler gemeckert -> der QWidget* parent solle nach hinten, warum auch immer...
Da würde mich die genaue Fehlermeldung interessieren.
Wahrscheinlich wegen der Angabe des Standardwerts= 0
(dieses darf nicht alleinig bei den ersten Parametern stehen - wie soll man dann die ersten Parameter auslassen?). Aber den kann man ja auch weglassen und jeweils explizit beim Aufruf setzen.
-
@stefanpc81 sagte in Zugriff von Instanzvariablen über std::bind?:
Die sollen aber nicht alle über die gleiche Klasse aufgerufen werden.
Ich verstehe nicht was du damit meinst.
Was soll "einen Wert aufrufen" bedeuten? Und was soll "über eine Klasse aufrufen" bedeuten?
-
Ich verstehe nicht was du damit meinst.
Was soll "einen Wert aufrufen" bedeuten? Und was soll "über eine Klasse aufrufen" bedeuten?Was wir hier für "N1" erarbeitet haben, sollte für die Klasse PaintEICAS verfügbar sein. "N2" soll über die noch nicht vorhandene Klasse "PaintMFD" verfügbar sein. Ich meinte eigentlich "in einer Klasse aufrufen". Mit "Wert aufrufen" meinte ich die "Membervariable auslesen". Da habe ich mich falsch ausgedrückt.
@Th69
Wegen der Fehlermeldung: Das konnte ich für dich leider nicht mehr rekonstruieren. Ich weiß nicht mehr, wie zu diesem Zeitpunkt der Code aussah.
-
@Th69
Ich habe gerade "deinen Fehler", den du wissen wolltest, gefunden! In der Headerdatei standclass PaintOHP : public QWidget { Q_OBJECT public: PaintOHP(QWidget* parent = Q_NULLPTR, const Engine* engineL, const Engine* engineR); //... }
was den Fehler
E0306 Das Standardargument befindet sich nicht am Ende der Parameterliste.
ausgelöst hat. Ich hatte fälschlicherweiseQWidget* parent = Q_NULLPTR
hier eingetragen und nach dem "Verschieben" dieser Initialisierung in den Konstruktor der CPP-Datei ist wieder alles gut.
Edit: War doch nicht alles gut. "Der 2. und 3. Standardparameter ist nicht definiert" hieß es. Erst nachdem ich= Q_NULLPTR
ganz rausgenommen habe, funktioniert alles.
-
Ja, genau das meinte ich.
Ich halte die Angabe des Standardwertes hier auch für überflüssig, da man ein Widget ja immer auf ein Window oder eine andere von Widget abgeleitete Klasse platziert und demnach explizit übergeben muß.Nur wenn es auch als eigenständiges Fenster angedacht ist, macht das m.E. Sinn - dann würde ich die Klasse aber auch explizit von
QWindow
ableiten (mit den entsprechenden Konstruktorparametern).Wie auch immer, ich hoffe, daß du jetzt mit deinem Projekt weiterkommst?!
-
Wie auch immer, ich hoffe, daß du jetzt mit deinem Projekt weiterkommst?!
Danke, das ist eine sehr freundliche Nachfrage von dir! Die Antworten haben mir sehr geholfen und mal abwarten, wann ich ein neues Problem habe und mich mit einem neuen Beitrag melde
-
Es geht (leider) schon weiter: Ich habe in der Qwidget-Klasse "PaintLowerControls" vor, die Werte von "Engine* engineL" zum Ändern zu bringen. Ich habe das const entfernt und mein Vorhaben scheitert offenbar daran, dass ich nicht mit den Zeigern und Referenzen ( * und &) klar komme bzw. mir noch das Verständnis dazu fehlt. Irgenwie muss ich hier ein & verwenden, aber ich verstehe nicht wie bzw. wo…
PaintLowerControls.cpp
PaintLowerControls::PaintLowerControls(QWidget* parent, Engine* engineL, Engine* engineR) : QWidget(parent), engineL(engineL), engineR(engineR) { QPushButton* leverLFuel = new QPushButton(this); leverLFuel->setGeometry(QRect(65, 230, 20, 30)); leverLFuel->setStyleSheet("background-color: transparent;" "border: 0px"); connect(leverLFuel, SIGNAL(clicked()), this, SLOT(ClickFuelLeverL(engineL))); } void PaintLowerControls::ClickFuelLeverL(Engine* engineL) { if (engineL->Get_lever_fuel() == "cutoff" && Current::GetLmain()) //soll alten Wert auslesen { //folgendes soll für den ursprünglichen Instanzmember engineL geändert werden engineL->Set_lever_fuel("run"); engineL->Set_fuel_valve(true); } //… }
PaintLowerControls.h
class PaintLowerControls : public QWidget { Q_OBJECT public: PaintLowerControls(QWidget* parent, Engine* engineL, Engine* engineR); ~PaintLowerControls(); void paintEvent(QPaintEvent* event); private slots: void ClickFuelLeverL(Engine* engineL); private: Engine* engineL; Engine* engineR; };
Engine.cpp
std::string Engine::Get_lever_fuel() const { return lever_fuel; } void Engine::Set_lever_fuel(std::string s) { lever_fuel = s; }
Engine.h
//… public: std::string Get_lever_fuel() const; void Set_lever_fuel(std::string s); //…
Current::GetLmain() gibt nebenbei bemerkt ein bool zurück. Ich wäre euch dankbar, wenn auch dieses Problem hier über das Forum gelöst werden könnte.
-
Was ist denn das genaue Problem? Kompiliert es nicht?
Was ich sehe ist, daß du bei
ClickFuelLeverL(...)
engineL
als Parameter übergibst, jedoch auch ohne diesen direkt auf die Membervariable zugreifen könntest.
BeimSLOT
mußt du die Signatur angeben und die Parameter getrennt bzw. einen Lambda-Ausdruck benutzen, s. z.B. Passing an argument to a slot.Wenn du
ClickFuelLeverL
immer mit derselbenEngine
benutzt (d.h. nurengineL
und nicht auch malengineR
), dann kannst du den Parameter einfach weglassen:connect(leverLFuel, SIGNAL(clicked()), this, SLOT(ClickFuelLeverL()));
sowie
void PaintLowerControls::ClickFuelLeverL() { // ... }
-
connect(leverLFuel, &QPushButton::clicked, this, [=](){ ClickFuelLeverL(engineL); });
war die Lösung! Danke!
Für engineL und R habe ich die Funktion getrennt geschrieben, da beide eine static-variable benutzen, in deren Klasse sich nur static Variablen bzw. Funktionen zum Lesen/Schreiben dieser Variablen befinden. Sie stellen nur Zustände dar und benötigen keinen Konstruktor. Ist vielleicht nicht die gängigste Vorgehensweise aber mir schien sie mir so am einfachsten.
-
@stefanpc81 sagte in Zugriff von Instanzvariablen über std::bind?:
Ist vielleicht nicht die gängigste Vorgehensweise aber mir schien sie mir so am einfachsten.
Einfach ist nicht immer gut