Qt 如何强制QActionGroup允许取消选中?
我在QActionGroup中有许多操作,因为我希望它们是独占的(如果选中了一个,那么所有其他操作都应该被取消选中)。但是,我也希望能够取消选中所有选项。此时,如果我选中action1,然后再次单击按钮,它将不会取消选中,取消选中的唯一方法是单击其他操作。简而言之,QActionGroup确保只检查了1个操作-我想确保只检查了1个或0个操作。有解决办法吗Qt 如何强制QActionGroup允许取消选中?,qt,pyside,Qt,Pyside,我在QActionGroup中有许多操作,因为我希望它们是独占的(如果选中了一个,那么所有其他操作都应该被取消选中)。但是,我也希望能够取消选中所有选项。此时,如果我选中action1,然后再次单击按钮,它将不会取消选中,取消选中的唯一方法是单击其他操作。简而言之,QActionGroup确保只检查了1个操作-我想确保只检查了1个或0个操作。有解决办法吗 我使用PySead,但是我也比较满意C++中的Qt,所以C++中的一个解决方案会很好,我确信我可以转换它。 代码(不是很有帮助,但我会在相关情
我使用PySead,但是我也比较满意C++中的Qt,所以C++中的一个解决方案会很好,我确信我可以转换它。 代码(不是很有帮助,但我会在相关情况下发布)
所有操作都是可检查的(在QT设计器中设置) 相关的:有一个类似于此的bug报告,但是设计者已经决定不改变任何东西:我用C++中的Qt代替Python,但是我希望这些信息可以帮助。 不幸的是,目前似乎没有直接解决这个问题的办法。
QActionGroup
的“exclusive”属性限制了选择功能,确保在任何时候至少且仅选择一个操作(但在程序开始时,您必须手动设置一个要“检查”的操作)
这是源代码的一部分,如果QActionGroup
{
if ( !isExclusive() )
return;
QAction* s = (QAction*) sender();
if ( b ) {
if ( s != d->selected ) {
d->selected = s;
for ( QPtrListIterator<QAction> it( d->actions); it.current(); ++it ) {
if ( it.current()->isToggleAction() && it.current() != s )
it.current()->setOn( FALSE );
}
emit activated();
emit selected( s );
} else if ( !s->isToggleAction() ) {
emit activated();
}
} else {
if ( s == d->selected ) {
// at least one has to be selected
s->setOn( TRUE );
}
}
}
class.cpp:
TheClass::TheClass()
{
QMenuBar *menuBar = new QMenuBar(this);
buffer = 0;
QMenu *menu = menuBar->addMenu("ActionList");
actionList.append(menu->addAction("Action0"));
actionList.append(menu->addAction("Action1"));
actionList.append(menu->addAction("Action2"));
for (int i=0; i<3; i++) {
actionList[i]->setCheckable(true);
}
connect(actionList[0], SIGNAL(triggered()), this, SLOT(action0Checked()));
connect(actionList[1], SIGNAL(triggered()), this, SLOT(action1Checked()));
connect(actionList[2], SIGNAL(triggered()), this, SLOT(action2Checked()));
connect(this, SIGNAL(selectedID(QAction*)), this, SLOT(compareChecked(QAction*)));
}
void TheClass::action0Checked()
{
if (actionList[0]->isChecked()) {
// do sth.
emit selectedID(actionList[0]);
}
}
void TheClass::action1Checked()
{
if (actionList[1]->isChecked()) {
// do sth.
emit selectedID(actionList[1]);
}
}
void TheClass::action2Checked()
{
if (actionList[2]->isChecked()) {
// do sth.
emit selectedID(actionList[2]);
}
}
void TheClass::compareChecked(QAction *newChecked)
{
if (newChecked != buffer) {
if (buffer != 0)
buffer->setChecked(false);
buffer = newChecked;
}
}
TheClass::TheClass()
{
QMenuBar*menuBar=新的QMenuBar(此);
缓冲区=0;
QMenu*menu=menuBar->addMenu(“操作列表”);
actionList.append(菜单->添加操作(“Action0”);
附加(菜单->添加操作(“操作1”);
附加(菜单->添加操作(“操作2”);
for(int i=0;isetCheckable(true);
}
连接(actionList[0],信号(triggered()),此,插槽(action0Checked());
连接(actionList[1],信号(triggered()),此,插槽(action1Checked());
连接(actionList[2],信号(triggered()),此,插槽(action2Checked());
连接(此,信号(选择EDID(QAction*)),此,插槽(比较选中(QAction*));
}
作废类::操作0已检查()
{
如果(actionList[0]->isChecked()){
//做某事。
发出selectedID(操作列表[0]);
}
}
作废类::action1Checked()
{
如果(actionList[1]->isChecked()){
//做某事。
发出selectedID(操作列表[1]);
}
}
作废类::action2Checked()
{
如果(actionList[2]->isChecked()){
//做某事。
发出selectedID(操作列表[2]);
}
}
void类::compareChecked(QAction*newChecked)
{
if(newChecked!=缓冲区){
如果(缓冲区!=0)
buffer->setChecked(false);
buffer=newChecked;
}
}
我知道已经好几年了。但我遇到了同样的问题,并在Qt论坛上找到了一个。它基本上是这样做的:
connect(action_group, &QActionGroup::triggered, [](QAction* action) {
static QAction* lastAction = nullptr;
if (action == lastAction)
{
action->setChecked(false);
lastAction = nullptr;
}
else
lastAction = action;
});
希望它对其他人的未来搜索有用
编辑:正如@Joe所建议的,这可以通过以下代码进一步改进:
connect(action_group, &QActionGroup::triggered, [lastAction = static_cast<QAction *>(nullptr)](QAction* action) mutable {
if (action == lastAction)
{
action->setChecked(false);
lastAction = nullptr;
}
else
lastAction = action;
});
connect(action\u group,&QActionGroup::triggered,[lastAction=static\u cast(nullptr)](QAction*action)可变{
if(action==lastAction)
{
操作->设置检查(假);
lastAction=nullptr;
}
其他的
最后行动=行动;
});
感谢您的帮助-明天我将尝试第二种方法(因为“无”选项在我的应用程序中不合适)。不客气。如果您在尝试第二个帖子时遇到任何问题,请随时更新帖子。感谢您提供的代码示例-它非常有用。我的新类正在按预期工作。再次感谢!这可以通过捕获lastAction=static_cast(nullptr)进一步改进
而是将lambda标记为可变的
。否则,窗口的多个实例将导致问题。我不理解部分lastAction=static\u cast(nullptr)
它应该放在第二行而不是static QAction*lastAction=nullptr;
还是应该放在第六行而不是lastAction=nullptr;
?还是应该同时放在这两行?它应该放在lambda的捕获列表中并替换静态变量。
connect(action_group, &QActionGroup::triggered, [](QAction* action) {
static QAction* lastAction = nullptr;
if (action == lastAction)
{
action->setChecked(false);
lastAction = nullptr;
}
else
lastAction = action;
});
connect(action_group, &QActionGroup::triggered, [lastAction = static_cast<QAction *>(nullptr)](QAction* action) mutable {
if (action == lastAction)
{
action->setChecked(false);
lastAction = nullptr;
}
else
lastAction = action;
});