QT: Zwei Events, wobei das erste das zweite ungültig macht -> Dump



  • Hi,

    ich habe nun nach langer Suche ein interessantes Problem entdeckt.

    Es gibt ein Textfeld, in dem Informationen geändert werden. Wenn sich diese Informationen ändern, wird ein Teil des UIs dynamisch neu erzeugt. Teile des UIs sind klickbar.

    Wenn ich jetzt in einem Textfeld bin, eine Änderung mache (noch kein Signal ausgelöst, erst bei Focusloss!) und dann auf ein Element meines dynamischen UI-Bereichs klicke, dumpt er.

    Wieso? Weil zunächst das Signal für die Änderung verarbeitet wird, wodurch die UI-Elemente gelöscht und neu erzeugt werden. Auf der Event-Queue befindet sich jedoch nach wie vor ein ausgeführter Rechtsklick, der verarbeitet werden soll. Das dazugehörige Objekt existiert jedoch nicht mehr -> Crash.

    Ich hätte gedacht, QT hätte das bedacht, doch ist nicht so (Version 4.7.x). Hat jemand eine Idee, wie ich dieses Problem umgehen kann? Irgendwelche anderen Vorschläge?

    Edit: Auch gut wäre, wenn ich irgendwie an die Eventqueue irgendwie rankäme, um dort manuell was zu löschen.



  • Eisflamme schrieb:

    Edit: Auch gut wäre, wenn ich irgendwie an die Eventqueue irgendwie rankäme, um dort manuell was zu löschen.

    Nee, das wäre nicht gut. Bloss nicht rumpfuschen 😉

    Ich kann zwar das Problem nachvollziehen, aber ich muss sagen, ich seh da jetzt eigentlich kein Problem. Schreibs halt so, dass du nicht in so eine Situation kommst. Das dürfte nicht so schwierig sein.


  • Mod

    Wie löscht du das dann?
    Ist evtl. deleteLater() eine Lösung?



  • Mechanics:
    Na ja, alle Lösungen wären in meinen Augen irgendwie Hacks. Ich könnte nach jeder Zeichenveränderung im Textfeld was ändern, dann müsste ich aber Paste ins Textfeld nochmal extra betrachten. Außerdem lässt sich das Textfeld auch über einen Auswahldialog ändern, das wäre ein weiterer Fall.

    phlox81:
    Huch, ich lösche es manuell über delete, obwohl es einen parent hat. Da liegt ganz klar der Fehler, deleteLater ist eigentlich perfekt. Ich werde versuchen das delete richtig anzuwenden, d.h. das Widget vorher auch aus dem Layout zu nehmen, vielleicht löscht das dann auch die Signale aus der Eventqueue... Vielen Dank 🙂

    Das kommt davon, wenn man 10h am Stück arbeitet, ich bin's nicht gewöhnt... Danke nochmals!

    Edit:
    Wobei deleteLater natürlich nicht dafür sorgt, dass der Rechtsklick auch auf das neue UI ausgeführt wird. Irgendwie müsste ich die Reihenfolge vertauschen, aber die Events kommen aus unterschiedlichen Ecken, hm...



  • Ich will dir ja keinen Hack oder Workaround vorschlagen (genaugenommen hab ich gar keine Lösung vorgeschlagen), sondern ich schlage dir vor, dein Konzept zu überdenken. Der Benutzer klickt auf etwas, was sich plötzlich verändert und zu etwas anderem wird? Hört sich nicht gut an. Kann man sicher auch irgendwie anders lösen. Schon vom Konzept her.



  • Ne, wollte Dir auch nicht unterstellen Hacks einzubauen. 🙂

    Logisch finde ich das schon in Ordnung. Es ist ein Analyseprogramm, was je nach Eingabe unterschiedliche Ausgaben macht. Dass also nach Eingabeänderung etwas verschwindet und etwas Neues auftaucht, ist zu erwarten. Und es macht für den Benutzer nach der Eingabe auch nicht viel Sinn, dass er auf das UI-Element klickt, das bei Fokusverlust verschwinden wird. Jedoch ist das technisch möglich und so könnte er es tun.

    Somit würde sich eigentlich ein deleteLater anbieten. Es ist jetzt nur so, dass ich der Einfachheit halber das UI einfach komplett zerstöre und neu erstelle statt zu schauen, was sich ändert und das zu löschen, was nicht mehr benutzt wird und neu hinzuzufügen, was nicht schon da ist etc. Es könnte somit also doch sein, dass der Benutzer eine sinnvolle Ausführung macht, auf die hin es nicht funktioniert, was gegen deleteLater spricht.

    Am Besten gefiele es mir daher, wenn vor dem Posten des ClickEvents zunächst die UI-Änderung geschieht und der Click dann erst im überarbeitenden UI ankommt, aber die Reihenfolge kann ich nicht so gut kontrollieren.



  • Es ist denke ich genauso verwirrend, wenn der Benutzer irgendwohin klickt, das Element verschwindet, stattdessen ein neues hinkommt, und die Aktion dann darauf ausgeführt wird. Wäre vielleicht besser, das restliche UI erstmal zu deaktivieren, und erst beim Verlassen der Eingabemaske wieder zu aktivieren.



  • es gibt auch noch ein QObject::disconnect.



  • Genau, aber das wird beim dtor ja sowieso automatisch ausgeführt. Das Problem ist, dass der Rechtsklick erkannt wird und ein Signal in die Queue gesteckt wird. Vorher steckte aber schon das Update-Signal drin. Daher wird dann das UI geupdated und dann das Klickevent auf das nun zerstörte Objekt ausgeführt.

    Disconnect sorgt ja nur dafür, dass bei einem Klick kein Event mehr "gezündet" wird. 🙂

    Edit:
    Also deleteLater sorgt schon Mal dafür, dass kein Crash mehr kommt. Bzgl. der anderen Auswirkung, dass sich der Rechtsklick auf das alte Widget bezieht, hatte ich jedoch auch Recht. Eine Lösung könnte in meinem Fall sein, das Widget noch häufiger zu aktualisieren, nämlich während die Eingabe stattfindet und insbesondere nach einem Paste.


Log in to reply