2013-03-02 10 views
5

Piszę aplikację C++ o nazwie qt. Mam wiele przycisków, które chcę wzajemnie się wykluczać - tylko jeden może być przełączany na raz. Generalnie używam do tego QButtonGroup - zapewnia to logiczny sposób zarządzania zestawami przycisków. Kiedy ktoś zostanie przyciśnięty, poprzednio przyciśnięty zostaje zniszczony, co jest właśnie pożądanym zachowaniem.Alternatywa dla QButtonGroup, która nie pozwala na wybór?

Tym razem jednak pozwolę, aby grupa została całkowicie odznaczona. Niestety, wydaje się to być zabronione przez QButtonGroup:

wykluczają: bool

Ta nieruchomość posiada czy grupa przycisk jest wyłączna.

Jeśli ta właściwość jest prawdziwa, tylko jeden przycisk w grupie może być sprawdzany w dowolnym momencie. Użytkownik może kliknąć dowolny przycisk, aby sprawdzić, czy jest to , a ten przycisk zastąpi istniejący jako sprawdzony przycisk w grupie.

W ekskluzywnej grupie, użytkownik nie może odznaczyć aktualnie zaznaczonego przycisku , klikając na niego; zamiast tego, inny przycisk w grupie musi być ustawiony na , aby ustawić nowy zaznaczony przycisk dla tej grupy.

Oczywiście istnieje kilka sposobów obejścia tego problemu. Zastanawiam się, czy istnieje gotowa alternatywa dla QButtonGroup, która pozwala na takie zachowanie, 1) nie odkrywam koła i 2) Mogę pozostać w obrębie idiomatic qt, aby ułatwić zarządzanie projektami w przyszłości.

Wszelkie sugestie?

+2

AFAIK Nie.Szczególnie w tym przypadku Kod wymagany do uzyskania Twojej funkcjonalności jest bardzo minimalny. Wyłącz wyłączną właściwość z grupy przycisków, gdy chcesz, aby wszystkie były odznaczone w filtrze zdarzeń/zdarzeniu naciśnięcia przycisku myszy, a obiekt nadawcy jest taki sam, jak bieżący naciśnięty przycisk. W przeciwnym razie włącz wyłączną własność, jeśli nie już. – Viv

+0

Trzy lata później, ale zauważyłem dzisiaj, że korzystając z autoexclusive zamiast QButtonGroup i Qt 4.8.6 mogę odznaczyć wybrany przycisk radiowy. Nie wiem, czy to błąd, czy nie. – Phlucious

Odpowiedz

1

W celu uzupełnienia, chciałbym opublikować tutaj jedno możliwe rozwiązanie problemu, ponieważ właśnie rozwiązałem go w moim przypadku. Po prostu pamiętaj, że poniższy kod jest ważny dla Qt3. Równie dobrze może działać dla Qt4 i Qt5, ponieważ nie używa wielu rzeczy.

Zakładam więc, że mam widżet CustomWidget, który zawiera przyciski (typu CustomButton) i że można włączyć jeden i tylko jeden przycisk. Jeśli klikniesz inny przycisk w widgecie, aktualnie włączony przycisk jest wyłączony, a nowo kliknięty przycisk jest włączony.

W CustomButtons zawarte w CustomWidget są zawarte w QButtonGroup w następujący sposób:

QButtonGroup* m_ButtonGroup = new QButtonGroup(this); 
m_ButtonGroup->hide(); 
m_ButtonGroup->insert(Btn1); 
m_ButtonGroup->insert(Btn2); 
m_ButtonGroup->insert(Btn3); 
m_ButtonGroup->setExclusive(true); 

Tutaj btn1, Btn2 i Btn3 są typu CustomButton

class CustomButton : public QToolButton 
{ 
    Q_OBJECT 

    public: 
    CustomButton (QWidget* apo_parent = 0, const char* as_name = 0); 
    virtual ~CustomButton(); 

    protected: 
    virtual void mousePressEvent(QMouseEvent* a_Event); 
}; 

Metoda ci chcesz zaimplementować specjalnie jest mousePressEvent. Jeśli jego ciało jest zaimplementowane w następujący sposób:

void CustomButton ::mousePressEvent(QMouseEvent* a_Event) 
{ 
    if(group() && isToggleButton()) 
    { 
    CustomButton* selectedButton(dynamic_cast<CustomButton*>(group()->selected())); 
    if(selectedButton) 
    { 
     if(selectedButton->name() == name()) 
     { 
     group()->setExclusive(false); 
     toggle(); 
     group()->setExclusive(true); 
     return; 
     } 
    } 
    } 
    QToolButton::mousePressEvent(a_Event); 
} 

to widget zachowuje się tak, jak chcesz.

1

W Qt5, użyć podobnego rozwiązania Laurent Michel, lecz stosując zamiast uwalniania zdarzenie przypadku Press:

// Allow to uncheck button in exclusive group 
void CustomButton::mouseReleaseEvent(QMouseEvent* a_Event) { 
    if(group()->checkedId()==group()->id(this)) { 
     if(isDown()) group()->setExclusive(false); 
    } 
    QToolButton::mouseReleaseEvent(a_Event); 
    group()->setExclusive(true); 
} 
Powiązane problemy