7
votes

Créez une fenêtre contextuelle dans QT sans ombre

Je développe une application à l'aide de Qt 4.5 (sous Windows Vista, mais veulent qu'elle soit multiplate-forme). J'utilise C ++

J'aimerais créer une fenêtre contextuelle qui contient un widget QLineDit, avec la fonctionnalité que lorsque l'utilisateur interagit avec le widget QLineDit, la fenêtre contextuelle n'est pas activée (la fenêtre de l'application principale reste active. ).

créer une fenêtre (widget) avec le qt :: popup | QT :: Les drapeaux de fenêtre me donne exactement ce que je veux, sauf que je ne veux pas l'effet de la frontière d'ombre 3D que cela fournit. Je veux une fenêtre sans bordure. Notez que le drapeau QT :: FramelessWindowhint n'atteint pas cela.

Quelqu'un a obtenu des indices?

Clarification supplémentaire: ci-dessous est un snippit d'une simple application de test qui crée une fenêtre avec un bouton. Lorsque vous appuyez sur le bouton, une fenêtre contextuelle est affichée et l'utilisateur peut taper dans une boîte QLineDit. Lorsque l'utilisateur le fait, la fenêtre principale reste activée:

http://howlettresearch.com/ popup_img_1.png

Cependant, notez la bordure de l'ombre sur la fenêtre contextuelle (je n'ai pas pu s'en débarrasser de cela).

par comparaison, créant la fenêtre comme Dans la ligne de sortie commentée permet de créer une fenêtre de style contextuelle sans ombre, mais lorsque l'utilisateur clique sur le QLineDit dans la fenêtre contextuelle, la fenêtre principale n'est plus active. Vous pouvez le savoir car l'ombre sur la fenêtre principale a changé.

http://howlettresearch.com /popup_img_2.png

Je suis vraiment après une fenêtre contextuelle qui se comporte comme si elle fait partie de la fenêtre principale. À titre de note latérale, la fenêtre contextuelle disparaît en cliquant à l'extérieur, mais c'est presque le comportement que je veux et je peux travailler avec cela et que vous pouvez travailler avec cela et votre grabin, etc. Pour faire ce que je veux ... à condition que je puisse me débarrasser de cette ombre! xxx


2 commentaires

Une capture d'écran de ce que vous avez un ce dont vous avez besoin serait utile.


Une ombre de widget de niveau supérieur est quelque chose que Windows tire, selon le thème. Il n'y a rien de qt-spécifique là-bas.


3 Réponses :


2
votes

Je pense que l'ombre que vous voyez est liée au thème Windows que vous utilisez. J'utilise le thème Windows Classic ici et je ne vois aucune ombre :)

Quoi qu'il en soit, que si vous connectez le signal TextChanged () du QLeDIT dans une action personnalisée qui restaure la fenêtre de la fenêtre principale? Quelque chose comme: xxx

Vous devrez créer une fente appelée setactive () et vous devez également placer le QLeDedit dans votre en-tête de classe de sorte que de la fonction Setactive () que vous pouvez Faites quelque chose comme: xxx

pour restaurer également la mise au point sur le QLineDit.


1 commentaires

Le problème avec ceci est la zone de texte souligne la mise au point, de sorte que l'utilisateur ne puisse pas entrer plus de texte sans ré-activer la fenêtre contextuelle. Je pense que vous avez raison sur l'ombre faisant partie du thème Windows.



6
votes

J'ai élaboré une solution à la question que j'ai postée plus tôt.

Premier, un widget Popup peut être créé en dérivant de qwidget avec des indicateurs qt :: fenêtre | Qt :: FramedessWindowhint . J'ai effectivement piraté qwidget_win.cpp pour vous assurer que ma fenêtre a le même style et le même style que la commande contextuelle fournie par WPF (0x96000000 et 0x08000088 respectivement), comme déterminé à l'aide de Spy ++, mais je ne pense pas que devrait compter.

Réglage du style de la fenêtre ne résout pas le problème d'activation de la fenêtre. La clé pour l'intercepter pour intercepter les messages Windows qui informe la fenêtre principale que la zone non client doit être mise à jour ( wm_ncactivate message). Cela peut être fait en fournissant une implémentation personnalisée de Qappllication :: Wineventfilter (msg * msg, résultat long *) .

Malheureusement, il suffit de manger inactivate wm_ ncactivate ne suffit pas, car il semble empêcher wm_activate et d'autres messages qui ont été générés d'être envoyés à la fenêtre contextuelle . Pour résoudre ce problème, j'ai une preuve de concept de travail où je génère les messages Windows requis dans wineventfilter après avoir attrapé un message wm_ncactivate approprié .

D'ici, il y a quelques détails à travailler pour que ce soit robuste (intercept wm_activateApp vous vient à l'esprit), puis enveloppez-le dans quelque chose de gentil et réutilisable.

Tout cela est spécifique à Windows, soyez intéressant à voir s'il existe des problèmes sous Linux.

Tout cela est un peu douloureux. J'espère que je n'ai pas manqué quelque chose d'évident ...


0 commentaires

4
votes

Essayez ce code étrange ci-dessous (testé sur qt v5. *): xxx pré>


p> xxx pré>

ne fonctionne que avec ceci Méthodes de séquence appelez. Si vous faites quelque chose de changement, nous avions popup avec l'ombre. (Magic :)))) P>

Edit h3>

Je trouve ce drapeau Qt :: nodropshadowwindowhint code> dans Enum qt :: windowflags code> (Qt v5.3). Qui est apparu dans une version de qt v5. *. Avec ce drapeau au-dessus du code, il faut ressembler à ceci. P>

//BasePopup.cpp
#include "BasePopup.h"

BasePopup::BasePopup(QWidget *parent)
    : QFrame(parent, Qt::Popup | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint)
{
    //---------------------- 
    //yours code here 
    //----------------------
}


0 commentaires