Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: Andere GUIs - Qt, GTK+, wxWidgets ::  QT - Wenn PC heruntergefahren wird, Slot ausführen  
Gehen Sie zu Seite 1, 2  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
Baumann.D.
Mitglied

Benutzerprofil
Anmeldungsdatum: 14.02.2017
Beiträge: 4
Beitrag Baumann.D. Mitglied 16:22:38 14.02.2017   Titel:   QT - Wenn PC heruntergefahren wird, Slot ausführen            Zitieren

Hallo zusammen,
bin ganz neu hier im Forum und hoffe es kann mir jemand helfen.

Ich habe ein Programm welches via UDP-Anfrage nach einem bestimmten "Arduino" im Netzwerk sucht, wird dieser gefunden baue ich eine TCP-Verbindung auf und kommuniziere so mit diesem. Das funktioniert auch soweit alles.

Jetzt geht es aber darum, wenn das Programm läuft und der PC heruntergefahren wird, soll zuvor noch ein Befehl via TCP gesendet werden um den Arduino in Standby zu schalten.

Ich habe bereits versucht "closeEvent" zu überschreiben:
C++:
void MainWindow::closeEvent(QCloseEvent *event)
{
    TcpWrite("Standby");
    event->accept();
}

-> Wird das Programm normal beendet wird auch der Befehl gesendet, jedoch nicht beim Herunterfahren des PC's


Desweiteren habe ich versucht über "aboutToQuit" den Slot "close" auszuführen:
C++:
1
2
3
4
5
6
7
8
9
10
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MainWindow window;
    window.show();
 
    QObject::connect(&app, SIGNAL(aboutToQuit()), &window, SLOT(close()));
 
    return app.exec();
}

-> Der Gedanke dabei war es, kommt das Signal "aboutToQuit" (laut Doku, wenn der PC Heruntergefahren wird) führe ich den Slot "close" (also auch mein closeEvent) aus.
-> funktioniert beim normalen schließen über "X" auch, jedoch nicht beim Herunterfahren


Ich hoffe man kann mir in etwa folgen und vielleicht weiß jemand eine Lösung

Gruß
Dominik
RHBaum
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.04.2003
Beiträge: 1360
Beitrag RHBaum Mitglied 18:11:14 14.02.2017   Titel:              Zitieren

Das wird nicht so einfach sein ... weil jeder sich da anders verhält.

Windows: es gibt ne Nachricht WM_ENDSESSION bzw WM_QUERYENDSESSION
darauf kann dein Prog hören, muss aber nicht ...
Wenn es nicht hört ... kriegt es WM_CLOSE, wenn es dann immer noch nicht kooperiert, kommt kill signal.

Linux:
Standard, ohne GUI ... was beim shutdown noch läuft kriegt nen SigTerm, nach ner Weile SigKill .

Mit Glück:
Dein system unterstützt DBUs, der sollte lustig signale umherschicken beim closen. Keine Ahnung ob die Standardisiert sind.
KDE und Gnome nutzen das eh glaub ich ...

Mit GUI:
XWindows/MIR ... keine Ahnung, das ding sendet auch messages, Keine Ahnung ob da nen Session close dabei ist. Thoerethisch sollten aber sogar aps das Sterben des XWindows überleben können, von daher vielleicht unwahrscheinlich das garantiert vorm session close was abbekommst.

Idee 1.
Nen Daemon / dienst statt nen "Normalen" Programm. Einschalten kann man Usergesteuert uber IPC machen, Das kannst mit nem normalen Prog dann ansteuern.
Und ausschalten geht ueber systemshutdown, bevor netz runterfährt natürlich.

Idee 2.
mem GUI Programm was sich im Tray einnistet und mit der Usersession im windowmanager lebt. Normal muesste der XServer vorm Netz gekillt werden. Iss aber für KDE/Gnome/Windows unnerschiedlich. WObei Qt Tray anbindung bietet, die auch unter windows geht, in KDE Sowieso ... wie es mit Gnome aussieht, ka.

Idee 3.
Keine Ahnung was der Ardino für ne Netzwerkkarte hat, was die kann ...
Aber router/FW davor, der die ganzen 0815 Broadcasts blockt, so das wirklich nur gezielte Ethernet frames bei dem ankommen.
und WOL / einschlafen passend configurieren ...

Ciao ...
partsoft
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.04.2016
Beiträge: 43
Beitrag partsoft Mitglied 13:42:45 15.02.2017   Titel:              Zitieren

Ich bin mir nicht sicher ob das funktioniert, aber hast du mal versucht eine Klasse von QApplication abzuleiten und den Code im Destruktor aufzurufen?

_________________
https://www.partsoft.de
Softwareentwicklung und Vertrieb
RHBaum
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.04.2003
Beiträge: 1360
Beitrag RHBaum Mitglied 10:11:19 16.02.2017   Titel:              Zitieren

Zitat:
hast du mal versucht eine Klasse von QApplication abzuleiten und den Code im Destruktor aufzurufen?

Zitat:
funktioniert beim normalen schließen über "X" auch, jedoch nicht beim Herunterfahren

Das ist doch sein Problem ...

DIe meisten Desktop Apps "brauchen" das shutdown verhalten nicht, deshalb reagieren sie auf die Signale des OS nichts. Ne App die noch offen ist wenn der WM closed, zumindest unter windows, die macht nix produktives mehr sondern die wird einfach gekillt.
Wenn das kill kommt, ists eh zu spät, weil das system "parallel" heruntergefahren wird, d.h. ob der Netzwerk-Stack noch vorhanden ist, ist gar ned garantiert.
Du wirst nicht mal richtig "testen" können, ob dein DTor aufgerufen wird, weil Deine App und Monitor/Debugger gleichzeitig sterben :-)


D.h. er muss vorher reagieren und sich selbst sauber runterfahren, und das geht nur ueber "Signale" oder Nachrichten vom OS ....

Ciao ...


Zuletzt bearbeitet von RHBaum am 10:13:59 16.02.2017, insgesamt 1-mal bearbeitet
partsoft
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.04.2016
Beiträge: 43
Beitrag partsoft Mitglied 14:32:34 16.02.2017   Titel:              Zitieren

[code]
#ifndef APPLICATION_H
#define APPLICATION_H

#include <QApplication>

class Application : public QApplication
{
public:
Application(int &argc, char **argv);
~Application();
};

#endif // APPLICATION_H
[/code]

[code]
#include "application.h"
#include <QDir>

Application::Application(int &argc, char **argv) : QApplication(argc, argv)
{
}

Application::~Application()
{
QDir dir;
dir.mkpath("C:/Users/shold/Documents/xyy");
}
[/code]

Mal schnell gebastelt und ausprobiert. Der Destruktor erstellt hier einfach nur ein Verzeichnis, ich sehe aber keinen Grund wieso man hier nicht auch noch einen TCP-Befehl senden könnte.

Unter Windows habe ich das erfolgreich getestet.


edit: Sorry funktioniert doch nicht, der Ordner war vorher schon da :rolleyes:

_________________
https://www.partsoft.de
Softwareentwicklung und Vertrieb


Zuletzt bearbeitet von partsoft am 14:35:40 16.02.2017, insgesamt 1-mal bearbeitet
Scorcher24
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.12.2004
Beiträge: 2573
Beitrag Scorcher24 Mitglied 14:54:43 16.02.2017   Titel:              Zitieren

Siehe:
http://doc.qt.io/qt-5/qcoreapplication.html#aboutToQuit

http://stackoverflow.com/ ....... -shutdown-or-logoff-in-qt

edit: Ahh, nvm, das hat er schon versucht :D.

Allerdings dürfte WM_ENDSESSION das sein, was du suchst, falls Windows.
https://msdn.microsoft.co ....... amp;MSPPError=-2147217396


Zuletzt bearbeitet von Scorcher24 am 14:56:57 16.02.2017, insgesamt 2-mal bearbeitet
Baumann.D.
Mitglied

Benutzerprofil
Anmeldungsdatum: 14.02.2017
Beiträge: 4
Beitrag Baumann.D. Mitglied 15:07:53 16.02.2017   Titel:              Zitieren

Hallo zusammen,

erst mal danke für eure Hilfe. :live:

Dein Tipp:
RHBaum schrieb:
Windows: es gibt ne Nachricht WM_ENDSESSION bzw WM_QUERYENDSESSION
darauf kann dein Prog hören, muss aber nicht ...
Wenn es nicht hört ... kriegt es WM_CLOSE, wenn es dann immer noch nicht kooperiert, kommt kill signal.


hat mir schon mal weitergeholfen! Folgendermaßen funktioniert es beim Herunterfahren

Ich habe eine neue Klasse "MyEventFilter" erstellt:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef MYEVENTFILTER_H
#define MYEVENTFILTER_H

#include <QAbstractNativeEventFilter>

#include <QApplication>
#include <windows.h>
 
 
class MyEventFilter : public QAbstractNativeEventFilter
{
 
private:
    virtual bool nativeEventFilter(const QByteArray &eventType, void *pMessage, long *pResult);
};

#endif // MYEVENTFILTER_H
myeventfilter.h

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "myeventfilter.h"
 
bool MyEventFilter::nativeEventFilter(const QByteArray &eventType, void *pMessage, long *pResult)
{
    const MSG &msg = *static_cast<MSG *>(pMessage);
 
    if(msg.message == ENDSESSION_CLOSEAPP)
    {
        qApp->quit();
        *pResult = 1;
        return true;
    }
    else return false;
}
myeventfilter.cpp


und den Filter "installiert":

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "mainwindow.h"
#include <QApplication>
#include <QCoreApplication>
#include "myeventfilter.h"
 
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MainWindow window;
    window.show();
 
    //QObject::connect(&app, SIGNAL(aboutToQuit()), &window, SLOT(close()));
 
    MyEventFilter * pMyEventFilter = new MyEventFilter;
    app.setQuitOnLastWindowClosed(false);
    app.installNativeEventFilter(pMyEventFilter);
 
 
    return app.exec();
}
main.cpp


Ich verstehe jetzt nur nicht warum ich "setQuitOnLastWindowClosed(false)" auf false setzen muss. Dass führt nämlich dazu, dass beim Herunterfahren die Nachricht zwar gesendet wird, wenn ich das Programm aber schließe der Task im Hintergrund weiterläuft und somit die Nachricht natürlich nicht raus geht.

Setze ich es aber auf true, funktioniert zwar das Schließen wieder aber das Herunterfahren nicht mehr.

Windows macht mich fertig :rolleyes:



Gruß Dominik


Zuletzt bearbeitet von Baumann.D. am 15:17:43 16.02.2017, insgesamt 1-mal bearbeitet
partsoft
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.04.2016
Beiträge: 43
Beitrag partsoft Mitglied 15:16:35 16.02.2017   Titel:              Zitieren

Ich hab nochmal experimentiert und die Methode QApplication::event() überschrieben:

Code:
1
2
3
4
5
6
7
8
9
bool Application::event(QEvent *e)
{
    if (e->type() == QEvent::Quit) {
        QDir dir;
        dir.mkpath("C:/Users/shold/Documents/xyy");
    }
 
    return QApplication::event(e);
}


Das hat jetzt funktioniert :)

_________________
https://www.partsoft.de
Softwareentwicklung und Vertrieb


Zuletzt bearbeitet von partsoft am 15:22:43 16.02.2017, insgesamt 1-mal bearbeitet
RHBaum
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.04.2003
Beiträge: 1360
Beitrag RHBaum Mitglied 11:09:23 17.02.2017   Titel:              Zitieren

Zitat:
Ich verstehe jetzt nur nicht warum ich "setQuitOnLastWindowClosed(false)" auf false setzen muss.

setQuitOnLastWindowClosed ist ne komfort funktion der QT Message Queue.
Wenn das aktiviert ist bedeutet:
Sobald das letzte Window(Mainwindow, Dialog, Widget im Window mode) geschlossen ist, springt er aus der Message Loop raus.
D.h. du kommst aus dem QApplication::exec() raus.
Meist heisst das, dein Prozess beendet sich (muss aber nicht, mann kann auch nach dem exec noch zeugs machen)

setQuitOnLastWindowClosed auf false bedeutet.
Sind alle windows zu, bleibt der noch lustig in der QT Message Queue. DU musst Expliziet QApplication::quit() aufrufen um da rauszukommen.

Nützlich für nonGui anwendungen die trotzdem die QT Message Quueue verwenden (Wegen Signal / Slot z.b.) oder GUI anwendungen die definiert zustände haben wo kein fenster offen ist (Aka kein Hauptfenster).

Zu deutsch:
ist setQuitOnLastWindowClosed true und du schliesst das letzte Fentser, geht er aus der Message queue raus.
D.H. alles was du danach noch reinstellst wird nicht mehr ausgeführt.
Achtung: Signal/Slot funktioniert ueber die Message queue. Sprich ist lestztes fenster zu, werden auch deine connections nimmer abgearbeitet.
Und ich vermute dein Senden wird auf Signale Slots aufbauen ...

Ciao ...


Zuletzt bearbeitet von RHBaum am 11:11:34 17.02.2017, insgesamt 2-mal bearbeitet
Baumann.D.
Mitglied

Benutzerprofil
Anmeldungsdatum: 14.02.2017
Beiträge: 4
Beitrag Baumann.D. Mitglied 10:39:17 22.02.2017   Titel:              Zitieren

Nochmal Danke für eure Hilfe. :live:

partsoft schrieb:
Ich hab nochmal experimentiert und die Methode QApplication::event() überschrieben:

Code:
1
2
3
4
5
6
7
8
9
bool Application::event(QEvent *e)
{
    if (e->type() == QEvent::Quit) {
        QDir dir;
        dir.mkpath("C:/Users/shold/Documents/xyy");
    }
 
    return QApplication::event(e);
}


Das hat jetzt funktioniert :)


Leider habe ich da wieder das gleiche Problem wie mit "closeEvent", beim Schließen funktioniert es zwar, beim Herunterfahren jedoch nicht.
Hat es bei dir beim Herunterfahren funktioniert?

Und hat vielleicht jemand ein Beispiel für den EventFilter?
Ich habe ziemlich komische Reaktionen des Programmes, klicke ich zum Beispiel auf einen Eintrag in der "menubar" schließt sich mein Programm?!

Gruß Dominik
C++ Forum :: Andere GUIs - Qt, GTK+, wxWidgets ::  QT - Wenn PC heruntergefahren wird, Slot ausführen  
Gehen Sie zu Seite 1, 2  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.