Je crée une application à l'aide de QT qui consiste en un widget utilisé comme arrière-plan de l'application et une interface de contrôle de l'utilisateur qui flotte ci-dessus. P>
Un exemple similaire est Google Maps, où la carte est en arrière-plan et que les commandes sont en haut de l'arrière-plan. P>
Mais la chose est que le widget de fond puisse être changé en un widget différent (il existe un widget qui affiche une carte, un autre widget qui affiche l'alimentation vidéo, ...) P>
Et la même chose se produit pour les boutons de l'interface de contrôle de l'utilisateur, ils ne sont pas directement liés à l'arrière-plan actuel et peuvent être modifiés de manière dinamique. P>
J'ai essayé d'utiliser une Qstackedlayout, en utilisant deux couches, le widget de fond et l'interface de contrôle de l'utilisateur. Mais vous ne pouvez pas interagir avec la couche d'arrière-plan car tous les clics sont bloqués par le widget à l'avant. p>
Toute suggestion? P>
3 Réponses :
Votre question est trop générique pour vous donner une réponse particulière, mais la solution la plus évidente consiste à mettre en œuvre des classes qui hérite de qwidget pour chaque composant possible de votre système. Dans votre exemple, je peux visualiser 2 composants distincts: fond et contrôles. L'arrière-plan stockerait toutes les données d'image, telles que des cartes et des vidéos, tandis que les commandes auraient les boutons interagir avec le système. Vous pouvez même casser l'arrière-plan dans différentes classes pour gérer l'image ou la vidéo. Je recommande d'utiliser une classe centrale de Guicontroller qui hérite de QOBJECT pour gérer toutes les interactions d'interface, telles que la connexion des signaux / emplacements ou de la mise en œuvre de toutes les animations, de cette façon, vous pouvez ajouter / gérer plusieurs widgets sans aller à la variables .CPP.
edit: strong> Avec votre commentaire, semble que votre principal problème est que vos événements de souris ne se propagent pas à vos widgets comme prévu. La raison en est probablement que vous ne définissez pas les relations parents / enfants entre les composants. Assurez-vous que vous appelez le constructeur QWidget par défaut dans vos classes de widgets personnalisées telles que ci-dessus: p> Lors de la création de la classe du contrôleur, définit les bonnes relations entre les composants. Dans le contexte de votre système, retenue à moi que tous les composants seront ajoutés en tant qu'enfilateurs de fond, il ressemble au ci-dessous: P> class Controller : public QObject
{
public:
Controller(QObject *parent = 0, Qt::WFlags flags = 0) : QObject(parent, flags)
{
wdg_back_= new BackWidget(this);
wdg_control_ = new Controls(wdg_back);
wdg_1_ = new GenericWidget(wdg_back);
//connect your signals/slots, etc
}
private:
BackWidget *wdg_back_;
Controls *wdg_control_;
GenericWidget *wdg_1_;
}
C'est l'approche que j'ai suivie, j'ai regroupé toutes les commandes en un seul widget, qui les contient avec les mises en page appropriées. Mais la chose est que même s'il y a quelques widgets dispersés à l'écran, ce widget de contrôle occupe tout l'écran et bloque les événements de la souris-clic. Une autre chose que je pense que cela pourrait résoudre ce problème, consiste à ajouter les commandes une par une comme des couches distinctes sur le widget empilé. De cette façon, ils ne bloqueront que les clics de la souris qui sont sur eux.
Êtes-vous sûr que vous ajoutez tous vos widgets comme des enfants de ce widget de contrôle / arrière-plan? Assurez-vous que vos constructeurs de widgets personnalisés appellent le constructeur par défaut QWidget et vous définissez le widget de titulaire (probablement le fond) comme le père de tous vos widgets pendant l'initialisation de l'interface graphique.
Le problème semble être celui qui a été discuté ici: qtcentre.org/ Fils / ... Depuis que j'utilise un empressementLayout avec deux widgets (l'arrière-plan et le widget de contrôle), le widget de contrôle, qui est en haut, bloque tous les événements de la souris-clic. Je vais essayer de définir le widget de contrôle en tant qu'enfants de l'arrière-plan, au lieu d'eux être des frères et sœurs.
Oui. Par votre commentaire, on dirait que le problème est exactement les considérations faites dans ma réponse modifiée. Vous l'avez lu? Le contrôle doit être un enfant de fond ou ne partagera pas la propagation des événements.
Oui, je le lis et je l'ai essayé, mais j'ai le même problème. Je crée d'abord le widget de fond, qui est une sous-classe de QGraphicsview (et cela appelle son constructeur parent), je l'ai défini comme widget central de mon QmainWindow. Ensuite, je crée le contrôle de contrôle, passant le widget et le parent de fond, le contrôleWidget est une sous-classe de QWidget et transmet l'argument parent au constructeur par défaut QWidget. La souris cliquée sont reçues dans le widget de contrôle, puis je les redirige dans le widget de fond à l'aide de QcoreApplication :: SendEvent (_bwidget, ev); Mais ils sont reçus chez Qmainwindow.
Pouvez-vous modifier votre question pour expliquer mieux votre approche actuelle? Peut-être poster un code utile.
Laissez-nous Continuer cette discussion en chat
Vous pouvez placer un filtre sur le flux d'événement sur vos widgets d'interface à l'aide de la Une autre option consiste à créer une classe dérivée de qObject :: Installeventfilter () code> fonction et intercepter tous les événements entrants de la souris. Une fois que vous avez capturé ces événements, utilisez la fonction de filtrage pour les déléguer au widget arrière-plan ou les livrer aux boutons d'interface avant. Vous devrez probablement utiliser les coordonnées (x, y) de la souris-cliquez pour déterminer si un événement devrait aller sur le widget de fond ou l'un des widgets de bouton de premier plan. P>
qabstractbutton code> (ou quel que soit QWIDGET que vous utilisez pour vos boutons) et rééménagez les fonctions d'événement pour les clics de souris sur ce widget (c.-à-d.
QabstractButton :: MousePresseVent () Code>, etc.). Lorsqu'un clic de souris arrive, vérifiez si la souris était sur le bouton, et si ce n'était pas, envoyez l'événement au widget de fond via un signal ou
QcoreApplication :: SendEvent () Code>. p>
C'est une bonne approche que je n'avais pas pensée, je vais certainement mettre en œuvre cela si je ne trouve pas une autre façon de les poser sans bloquer les événements de la souris-clic.
J'ai essayé de la mettre en œuvre, j'essaie actuellement de transmettre tous les sourisPresseVents au widget de fond avec: QcoreApplication :: SendEvent (_bwidget, ev); À l'intérieur du gestionnaire de sourisServent, mais ils sont reçus dans le parent du widget de fond plutôt que dans le widget de fond lui-même.
Votre objet de fond doit également réimplément MousePressevent () code> ou
événement () code> afin de pouvoir traiter correctement les événements que vous envoyez ... sinon les implémentations par défaut de ces fonctions dans la classe de base que vous avez dérivé de volonté renvoie simplement
false code> et que le parent sera alors le destinataire de l'événement.
OK J'ai enfin trouvé une solution pour mon problème.
Mon approche de l'utilisation de Qstackdwidget était fausse, le widget sur le fond n'est pas censé être cliquable, et même si cela pourrait être fait, ce n'est pas ce que j'étais à la recherche. p>
à la fin, c'est ce que j'ai fait: p> donc je crée un qwidget, Centralwidget qui sera le parent de l'arrière-plan et le premier plan. Définissez l'arrière-plan sur plein écran et organisez les commandes dans un QGriDlayout qui n'affecte pas le fond de fond. P> Si je clique sur un contrôle, l'événement est traité par ce contrôle, mais en cliquant sur un vide L'espace déclenchera un événement de souris sur le fondwidget, qui est ce dont j'avais besoin. p> Je vais tester cela pendant un certain temps et si cela fonctionne bien, je fermai la question. P> P> P> P> P> P> >