2015-12-06 45 views
3

在我的Qt5程序中,我正在處理多個對象,並且需要大量時間和代碼來禁用或更改20個複選框的狀態。是否有任何選項可以製作一組複選框(或任何其他對象)並使用一行命令對其執行命令?對象組

例如:

QCheckBox b1, b2, b3, b4, b5; 
QCheckBox_Group Box_1to5 = {b1, b2, b3, b4, b5}; 
ui->Box_1to5->setEnabled(false); 

這可能嗎?

+1

取決於您想要達到的目標。有QButtonGroup:http://doc.qt.io/qt-5/qbuttongroup.html,但更多的是對於一次只能檢查一個按鈕的專屬組。如果是關於啓用/禁用:如果所有複選框都位於同一父級內,則可以啓用/禁用父級。或者將複選框放入矢量中並對它們進行迭代。 –

+1

@Frank,這應該是一個答案,而不是評論,因爲你已經介紹了它。我只是補充說,另一種方法是通過包裝這些向量來創建自定義的組類(或者,而不是'QList's)。 –

+1

製作自己的複選框管理器,並在對象組上執行任何操作。如果你不想要單獨的課程,那麼只需要簡單的循環。 –

回答

1

弗蘭克的評論是你想要的只是啓用/禁用一組小部件,但我會回答你更一般的問題,就是如何將狀態改變應用到一組對象。如果您可以自由使用C++ 11,那麼下面就給你調用任何成員函數的任何物體上一組通用的函數參數的一般能力:

// Member functions without arguments 
template<typename ObjectPtrs, typename Func> 
void batchApply(ObjectPtrs objects, Func func) 
{ 
    for (auto object : objects) 
    { 
     (object->*func)(); 
    } 
} 

// Member functions with 1 or more arguments 
template<typename ObjectPtrs, typename Func, typename ... Args> 
void batchApply(ObjectPtrs objects, Func func, Args ... args) 
{ 
    for (auto object : objects) 
    { 
     (object->*func)(args ...); 
    } 
} 

通過以上,就可以實現您的目標是能夠用一行代碼調用一組對象上的函數。你會使用它是這樣的:

QCheckbox b1, b2, b3, b4, b5; 
auto Box_1to5 = {b1, b2, b3, b4, b5}; 

batchApply(Box_1to5, &QCheckbox::setChecked, false); 
batchApply(Box_1to5, &QCheckbox::toggle); 

上述方法的一個限制是,它不處理函數默認參數,因此,即使一個功能有一個默認的參數,你必須明確提供一個。例如,下面將導致編譯錯誤,因爲animateClick有一個自變量(它的缺省值被忽略):

batchApply(Box_1to5, &QCheckbox::animateClick); 

上述技術使用可變參數模板支持的函數的參數的任何數量和類型。如果您還不熟悉這些,你可能會發現以下有用:

https://crascit.com/2015/03/21/practical-uses-for-variadic-templates/

2

您可以定義一個信號和連接,爲所有的複選框:

/* In the constructor or at the start*/ 
QVector<QCheckbox*> boxes{b1, b2, b3, b4, b5}; 
for(QCheckbox* box: boxes) { 
    connect(this, &MyWidget::setBoxCheckedState, box, &QCheckbox::setChecked); 
} 

/* Somewhere in the code where the state should change */ 
emit setBoxCheckedState(true); // <- custom signal on your class 

,或者你可以使用for_each算法:

bool checked = true; 
std::for_each(boxes.begin(), boxes.end(), [checked](QCheckbox* box) { 
    box->setChecked(checked); 
});