程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 探討多個QRadioButtons的AutoExclusive的問題

探討多個QRadioButtons的AutoExclusive的問題

編輯:關於.NET

在寫代碼的過程中, 遇到一個問題:

原來有一個UI文件, 將5個RadioButton分成2組, 前三個(例如: radioBtn1,radioBtn2, radioBtn3)和 後兩個(radioBtn4, radioBtn5)各放在一個VeticallyLayout裡. QT Designer中的截圖如下所示:

在代碼裡, 兩組都可以獨立工作, 互不干擾. 以下為例:

void testFun()
{
  ...
  radioBtn1->setChecked(false);
  radioBtn2->setChecked(true);
  radioBtn3->setChecked(false);
  ...
  radioBtn4->setChecked(true);
  radioBtn5->seteChecked(false);
  ...
}

程序運行後可以看到, radioBtn2和radioBtn4是選中的.

後來我修改了UI文件, 將兩組又放在了一個VeticallyLayout裡, 如下圖所示:

代碼未變, 但是運行後發現, 上面3個始終選不中. 只有下面2個是可以正常work的. 百思不得其解... 中間的解決過程費了不少腦細胞, 又是仔細比較.ui文件, 又是找人幫忙, 最終在一位牛人點解下回到起 點: 求助QT Qssistant.

在QT Assistant中關於QRadioButton, 寫有這樣的話:

A QRadioButton is an option button that can be switched on (checked) or off (unchecked). Radio buttons typically present the user with a "one of many" choice. In a group of radio buttons only one radio button at a time can be checked; if the user selects another button, the previously selected button is switched off.

Radio buttons are autoExclusive by default. If auto-exclusive is enabled, radio buttons that belong to the same parent widget behave as if they were part of the same exclusive button group. If you need multiple exclusive button groups for radio buttons that belong to the same parent widget, put them into a QButtonGroup.

不難看出什麼意思了吧? 同屬於一個相同的父widget的radiobuttons是autoExclusive的.

在我的代碼中, radioBtn2雖然是被選中的, 但是之後的radioBtn4將其沖掉了. 這種情形, 只能老老 實實用QButtonGroup(parent is QObject)或者QGroupBox(parent is QWidget)來將兩組分開了.

代碼如下:

// in ctor
{
  ui.setupUi(this);
  
  ...
  
  // use QButtonGroup to excluse from the two QRadioButtons below.
  QButtonGroup *btnGroup = new QButtonGroup(this);
  btnGroup->addButton(ui.radAllConnections);
  btnGroup->addButton(ui.radListedConnections);
  btnGroup->addButton(ui.radNoTrust);
  
  ...
}

但是有個問題, the same parent widget是說同一個父widget, QLayout不是QWidget的子類啊????? 在另外一個高人點解下, 發現, 原來的UI中, 雖然放在了兩個Vertically Layou中, 但是, 其實是放在了 一個QWidget中. 查看UI文件的code可以看到:

verticalLayout_3 = new QVBoxLayout();
layoutWidget2 = new QWidget(settings_firewall_page); //這是radAllConnections, 

radListedConnections和radNoTrust的parent Widget.
layoutWidget2->setObjectName(QString::fromUtf8("layoutWidget2"));
layoutWidget2->setGeometry(QRect(120, 440, 144, 96));
verticalLayout_4 = new QVBoxLayout(layoutWidget2);
verticalLayout_3 = new QVBoxLayout();
verticalLayout_3->setObjectName(QString::fromUtf8("verticalLayout_3"));
radAllConnections = new QRadioButton(layoutWidget2);
radAllConnections->setObjectName(QString::fromUtf8("radAllConnections"));
QSizePolicy sizePolicy5(QSizePolicy::Preferred, QSizePolicy::Preferred);
sizePolicy5.setHorizontalStretch(0);
sizePolicy5.setVerticalStretch(0);
sizePolicy5.setHeightForWidth(radAllConnections->sizePolicy().hasHeightForWidth());
radAllConnections->setSizePolicy(sizePolicy5);
verticalLayout_3->addWidget(radAllConnections);
radListedConnections = new QRadioButton(layoutWidget2);
radListedConnections->setObjectName(QString::fromUtf8("radListedConnections"));
sizePolicy5.setHeightForWidth(radListedConnections->sizePolicy().hasHeightForWidth());
radListedConnections->setSizePolicy(sizePolicy5);
verticalLayout_3->addWidget(radListedConnections);
radNoTrust = new QRadioButton(layoutWidget2);
radNoTrust->setObjectName(QString::fromUtf8("radNoTrust"));
sizePolicy5.setHeightForWidth(radNoTrust->sizePolicy().hasHeightForWidth());
radNoTrust->setSizePolicy(sizePolicy5);
verticalLayout_3->addWidget(radNoTrust);
verticalLayout_4->addLayout(verticalLayout_3);
/*****************************/  
layoutWidget3 = new QWidget(settings_firewall_page); //radPingOn和radPingOff的parent Widget.
layoutWidget3->setObjectName(QString::fromUtf8("layoutWidget3"));
layoutWidget3->setGeometry(QRect(120, 310, 141, 111));
verticalLayout = new QVBoxLayout(layoutWidget3);  
verticalLayout_2 = new QVBoxLayout();
verticalLayout_2->setSpacing(10);
verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2"));
radPingOn = new QRadioButton(layoutWidget3);
radPingOn->setObjectName(QString::fromUtf8("radPingOn"));
sizePolicy5.setHeightForWidth(radPingOn->sizePolicy().hasHeightForWidth());
radPingOn->setSizePolicy(sizePolicy5);
verticalLayout_2->addWidget(radPingOn);
radPingOff = new QRadioButton(layoutWidget3);
radPingOff->setObjectName(QString::fromUtf8("radPingOff"));
sizePolicy5.setHeightForWidth(radPingOff->sizePolicy().hasHeightForWidth());
radPingOff->setSizePolicy(sizePolicy5);
verticalLayout_2->addWidget(radPingOff);
verticalLayout->addLayout(verticalLayout_2);

這兩組RadioButton的parent Widget分別是layoutWidget2和layoutWidget3. 因此, 它們不屬於the same parent widget, 可以實現各自的autoExclusive.

後來我修改的時候, 將這兩組RadioButton又放在了一個VerticallyLayout中, 然後與其他的widgets 一起, 放在了同一個Page上(QWidget). 此時生成的ui代碼是:

...
void setupUi(QWidget *settings_firewall_page)
{
  ...
  verticalLayout_6 = new QVBoxLayout(settings_firewall_page); //這是5個RadioButtons的

parent widget.
  
  ...
  verticalLayout_3 = new QVBoxLayout();
  verticalLayout_3->setObjectName(QString::fromUtf8("verticalLayout_3"));
  radAllConnections = new QRadioButton(settings_firewall_page);
  radAllConnections->setObjectName(QString::fromUtf8("radAllConnections"));
  QSizePolicy sizePolicy4(QSizePolicy::Preferred, QSizePolicy::Preferred);
  sizePolicy4.setHorizontalStretch(0);
  sizePolicy4.setVerticalStretch(0);
  sizePolicy4.setHeightForWidth(radAllConnections->sizePolicy().hasHeightForWidth());
  radAllConnections->setSizePolicy(sizePolicy4);
  verticalLayout_3->addWidget(radAllConnections);
  radListedConnections = new QRadioButton(settings_firewall_page);
  radListedConnections->setObjectName(QString::fromUtf8("radListedConnections"));
  sizePolicy4.setHeightForWidth(radListedConnections->sizePolicy().hasHeightForWidth

());
  radListedConnections->setSizePolicy(sizePolicy4);
  verticalLayout_3->addWidget(radListedConnections);
  radNoTrust = new QRadioButton(settings_firewall_page);
  radNoTrust->setObjectName(QString::fromUtf8("radNoTrust"));
  sizePolicy4.setHeightForWidth(radNoTrust->sizePolicy().hasHeightForWidth());
  radNoTrust->setSizePolicy(sizePolicy4);
  verticalLayout_3->addWidget(radNoTrust);
  verticalLayout_4->addLayout(verticalLayout_3);
  ...
  verticalLayout_5->addLayout(verticalLayout_4);
  ...
  verticalLayout_2 = new QVBoxLayout();
  verticalLayout_2->setSpacing(10);
  verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2"));
  radPingOn = new QRadioButton(settings_firewall_page);
  radPingOn->setObjectName(QString::fromUtf8("radPingOn"));
  sizePolicy4.setHeightForWidth(radPingOn->sizePolicy().hasHeightForWidth());
  radPingOn->setSizePolicy(sizePolicy4);
  verticalLayout_2->addWidget(radPingOn);
  radPingOff = new QRadioButton(settings_firewall_page);
  radPingOff->setObjectName(QString::fromUtf8("radPingOff"));
  sizePolicy4.setHeightForWidth(radPingOff->sizePolicy().hasHeightForWidth());
  radPingOff->setSizePolicy(sizePolicy4);
  verticalLayout_2->addWidget(radPingOff);
  verticalLayout->addLayout(verticalLayout_2);
  ...
  verticalLayout_5->addLayout(verticalLayout);
  ...
  horizontalLayout->addLayout(verticalLayout_5);
  ...
  
  verticalLayout_6->addLayout(horizontalLayout);
  
  ...
}

可以看出, 這5個RadioButton的parent Widget都變成了同一個settings_firewall_page!

因此, 這5個之間才是真正autoExclusive的. TrollTech的SE這樣處理, 可能是基於優化ui文件的考量 吧, 我還沒有更深的認識. 哪位知道的朋友可以告知. 謝謝先!

個人總結: 安全起見, 最好是在QT Designer裡將兩組分別放在一個QGroupBox裡, 或者在source codes裡, 用QButtonGroup將其分組.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved