Bienvenue sur le forum !

Si vous souhaitez rejoindre la communauté, cliquez sur l'un de ces boutons !

Qt 5 : 5.9.1 - Qt Creator : 4.3.1 - Qt Installer : 2.0.3 - JOM : 1.1.2 - Qt Build suite : 1.7.0 - VS Qt 5 : 2.0.0

[Qt4] ItemDelegate, focus sur une cellule

Bonjour,

Contexte : J'utilise un QTableWidget, dans lequel j'utilise des itemdelegate afin d'afficher different type de widget dans mes cellules (combo, lineedit ...etc). Version Qt 4.2.2. Je veux pouvoir accéder directement à mes données, sans faire de double click sur la cellule, pour cela je me sers de la fonction setEditTriggers appliquée à ma table avec comme argument CurrentChanged . Jusque là pas de probleme, l'edition de ma cellule se fait lorsque je clique sur celle ci ou bien par tabulation.

Problème : quand l'application est mise en tache de fond (on utilise un navigateur par exemple), le focus est perdu lorsqu'on revient à l'application, ou plus précisément la cellule est bien selectionnée, mais elle n'est plus en mode édition. Pour visualiser exactement mon probleme, il suffit de prendre l'exemple de démo spinboxdelegate et d'appliquer setEditTriggers(CurrentChanged) à la table, de lancer l'appli, de sélectionner une cellule (qui est éditée sur un simple click), puis de mettre l'appli en tache de fond, et d'y revenir : la cellule n'est plus édité mais est comme gelée.

Exemple du comportement que je voudrais avoir : la table Property Editor du designer : si on edite l'une des lignes, qu'on met le designer en tache de fond et qu'on revient à lui, notre cellule est toujours en edition !

Je ne sais pas si c'est un problème spécifique aux itemdelegate, à la fonction editTrigger, ou un probleme plus général (rafraichissement par exemple), et vos lumières sont les bienvenues.

Réponses

  • Salut,

    Je vais peut-être dire une bêtise, mais qu'en est-il si tu refuses le leaveEvent envoyé à l'éditeur? Après j'imagine bien une interception de perte du focus au niveau de la fenêtre principale, qui récupère le widget qui avait le focus, et lui rend après reprise du focus, mais ça me semble plus un gros hack de barbare :P
    Sinon, use the source Luke ;)
  • j'ai fais un petit e.ignore(), dans la réimplémentation de leaveEvent(e), mais ca ne change rien. Je l'ai tenté dans la qDialog contenant ma table et dans la classe héritant du qtablewidget, mais dans les deux cas je ne récupère pas mon focus. Est ce bien cela que tu voulais que je fasse ?
  • Il ne suffirait pas de jouer avec le showEvent() de la dialogue pour remettre en edition la cellule courante ?!


    P@sNox,
  • D'apres la doc, l'evenenement showEvent n'est envoyé que quand on ouvre le widget (show() )ou lorsqu'il est réouvert après iconnification. Et effectivement, lorqu'on teste, le signal n'est généré qu'à l'apparition du widget et pas dans le cas qui m'interesse.
  • showEvent est apellé lors d'un apelle a show() ( ou c'est derivés showFullscreen() etc ) mais aussi lors de l activation d'une fenetre ( reduction, restauration ).

    cf Doc :
    Note: A widget receives spontaneous show and hide events when its mapping status is changed by the window system, e.g. a spontaneous hide event when the user minimizes the window, and a spontaneous show event when the window is restored again. After receiving a spontaneous hide event, a widget is still considered visible in the sense of isVisible().
    Si vraiment ca ne va toujours pas, il existe d'autre event ( changeEvent et en verifiant que l'event soit de type QEvent::ActivationChange, etc )

    P@sNox,
  • Mamat said:
    j'ai fais un petit e.ignore(), dans la réimplémentation de leaveEvent(e), mais ca ne change rien. Je l'ai tenté dans la qDialog contenant ma table et dans la classe héritant du qtablewidget, mais dans les deux cas je ne récupère pas mon focus. Est ce bien cela que tu voulais que je fasse ?
    Pour la seconde solution, je pensais à réimplémenter les focusInEvent et focusOutEvent au niveau de ton dialogue/fenêtre principale. Lors de l'appel de focusOutEvent, tu récupéres la cellule en cours d'édition, et tu mets cette info de côté. Lorsque focusInEvent est appellé tu recréé l'éditeur pour la cellule dont le pointeur a été gardé précédemment.
    Ca me paraît plus correct que les focus; le delegate étant probablement fermé par Qt lors de la sortie.

    Si ça ne marche pas, il ne te reste plus qu'à plonger dans le code du designer ;)

    PS: en annexe de la doc de Qt, les focusIn/OutEvent ne sont pas restreint au clavier; il suffit de regarder la doc de QFocusEvent pour s'en convaincre ;)
  • En utilisant focusIn et focusOut dans ma classe héritant du QTableWidget, on s'en sort. Il faut juste faire gaffe à la reason du focusIn, car à chaque changement de cellule (par tabulation), il y a un Out et un In d'envoyés, et dans ces cas la, pas besoin de réédité mon Item. Voila le bout de code (en python car je sais que vous aimez tous ca) :
    def focusInEvent(self,e):
    if self.curIt and e.reason() in (3,0):
    self.editItem(self.curIt)

    def focusOutEvent(self,e):
    self.curIt = self.currentItem()
    Merci les gars en tout cas pour votre aide précieuse.
  • Waou, limite HS, mais en python, vous avez pas un espèce d'enum pour les raisons?? (et pour le reste du coup :D)
  • si tu parles du (0,3), c'est juste une liste, donc si le numero de raison se trouve dans cette liste alors j'édite mon item.
    C'est plus convivial que d'avoir à écrire if e.reason() == 0 or e.reason() ==3 !
  • Ouaip, mais moins explicite que: if(reason == Qt::ActiveWindowFocusReason) ou équivalent.
    C'est à ça que je faisais référence en fait ;)
Connectez-vous ou Inscrivez-vous pour répondre.