2010-04-26 3 views
3

Il ya longtemps, j'ai essayé de trouver une méthode pour coller la fenêtre QDialog à l'écran des frontières pour mes petits projets comme Skype Windows le faire, mais j'ai échoué. Peut-être que je regardais ce code pas au bon endroit, alors maintenant je regarde la solution ici, sur la pile! :)Comment coller QDialog à l'écran Bordures comme Skype faire?

Alors, est-ce que quelqu'un a un accord avec une sorte de code, des liens, des échantillons?

À mon avis, nous devons réimplémenter fonction QDialog moveEvent, comme ci-dessous, mais ce code ne fonctionne pas ne:

void CDialog::moveEvent(QMoveEvent * event) { 

    QRect wndRect; 
    int leftTaskbar = 0, rightTaskbar = 0, topTaskbar = 0, bottomTaskbar = 0; 
// int top = 0, left = 0, right = 0, bottom = 0; 

    wndRect = this->frameGeometry(); 

    // Screen resolution 
    int screenWidth = QApplication::desktop()->width(); 
    int screenHeight = QApplication::desktop()->height(); 

    int wndWidth = wndRect.right() - wndRect.left(); 
    int wndHeight = wndRect.bottom() - wndRect.top(); 

    int posX = event->pos().x(); 
    int posY = event->pos().y(); 

    // Snap to screen border 
    // Left border 
    if (posX >= -m_nXOffset + leftTaskbar && 
     posX <= leftTaskbar + m_nXOffset) { 
     //left = leftTaskbar; 
     this->move(leftTaskbar, posY); 
     return; 
    } 

    // Top border 
    if (posY >= -m_nYOffset && 
     posY <= topTaskbar + m_nYOffset) { 
     //top = topTaskbar; 
     this->move(posX, topTaskbar); 
     return; 
    } 

    // Right border 
    if (posX + wndWidth <= screenWidth - rightTaskbar + m_nXOffset && 
     posX + wndWidth >= screenWidth - rightTaskbar - m_nXOffset) { 
     //right = screenWidth - rightTaskbar - wndWidth; 
     this->move(screenWidth - rightTaskbar - wndWidth, posY); 
     return; 
    } 

    // Bottom border 
    if (posY + wndHeight <= screenHeight - bottomTaskbar + m_nYOffset && 
     posY + wndHeight >= screenHeight - bottomTaskbar - m_nYOffset) { 
     //bottom = screenHeight - bottomTaskbar - wndHeight; 
     this->move(posX, screenHeight - bottomTaskbar - wndHeight); 
     return; 
    } 

    QDialog::moveEvent(event); 
} 

Merci.

Répondre

1

Comme vous pensiez pouvoir le faire dans la fonction moveEvent. Je suppose que le code suivant l'affaire, mais depuis que je n'ai rien à tester ici, je vais écrire un code pseudo:

D'abord obtenir la zone d'écran disponible:

const QRect screen = QApplication::availableGeometry(this); 
// This get the screen rect where you can drag a dialog 

ensuite obtenir la position de votre dialogue relatif sur le bureau (si votre dialogue est un enfant d'un autre widget, vous devez transformer les coordonnées par rapport à un widget parent bureau):

const QRect dialog = geometry(); 
// Do here transformation 

tester maintenant, si dialogue est frontière près de l'écran

if(abs(dialog.left()-screen.left() < OFFSET) 
    move(screen.left(), dialog.top(); 
else if(abs(dialog.top()-screen.top() < OFFSET) 
    move(dialog.left(), screen.top()) 
// etc. for the 2 other cases 

Permettez-moi de savoir si cela fonctionne

+0

@Patrice Bernassola: Merci pour votre réponse. Je pense que je dois mettre à jour mon échantillon, car il est plus prêt pour les tests/éditions ... Comme je suis un utilisateur linux depuis longtemps, dans KDE il y a des solutions globales pour ce cas: toutes les fenêtres/boîtes de dialogue peuvent être collées aux frontières de Windows, alors peut-être c'est une bonne idée de regarder dans les sources de KDE ... – mosg

1

Dans la pos propriété description de la documentation QWidget, il est le suivant avertissement sur le déplacement d'une fenêtre dans la méthode de gestion des événements de déplacement.

Avertissement: Appel move() ou setGeometry() à l'intérieur moveEvent() peut conduire à une récursion infinie.

Cela dit, il n'y a pas de moyen approprié de coller la fenêtre de dialogue à l'intérieur de la bordure de l'écran.

Remarque: Le comportement que vous avez observé dans KDE provient du gestionnaire de fenêtres. En fait, le gestionnaire de fenêtres est celui qui organise les fenêtres de l'application (comme les boîtes de dialogue) pour les afficher à l'écran. Le gestionnaire de fenêtres KDE a une option pour que toutes les fenêtres d'application (appelées client) restent sur la bordure.

+0

Merci pour la réponse. Je vais essayer votre solution demain, mais à l'origine, il y avait un code ... – mosg

+1

Code qui ne fonctionne pas réellement ... J'ai été en mesure de restaurer la position du widget afin qu'il puisse coller avec la bordure de l'écran. Mais dans certains cas, le traitement des événements a commencé à tourner indéfiniment. Je peux restaurer le code mais vous devriez maintenant que cela ne fonctionnera pas dans certains cas. – Lohrun

+0

Oui, je l'ai vérifié, et cela ne fonctionne que très bien avec la bordure supérieure, et pas avec les autres.C'est triste, mais cela signifie que nous sommes sur la bonne voie pour résoudre ce problème ... – mosg

Questions connexes