【问题标题】:Enabling QCheckBox when QCheckBox is checked选中 QCheckBox 时启用 QCheckBox
【发布时间】:2016-04-13 12:10:30
【问题描述】:

我是 Qt 和 GUI 编程的新手,当参数列表不匹配时,我不确定将信号连接到插槽的最佳方式。我有一个使用 Qt Designer 制作的设置对话框,它包含一系列 QCheckBoxes 和 QLineEdits,默认情况下禁用 QLineEdits。我想在 QLineEdit 旁边的 QCheckBox 被选中时启用它。

起初我想将 QCheckBox::stateChanged 信号连接到 QLineEdits::setEnabled 插槽,但是当我查看时发现它们具有不同的参数类型,所以这显然行不通:

connect(checkBox1, SIGNAL(stateChanged(int)), lineEdit1, SLOT(setEnabled(bool)));
connect(checkBox2, SIGNAL(stateChanged(int)), lineEdit2, SLOT(setEnabled(bool)));
connect(checkBox3, SIGNAL(stateChanged(int)), lineEdit3, SLOT(setEnabled(bool)));

接下来我想在对话框类中创建 setLineEditEnabled(int) 函数,以便在选中 QCheckBox 时启用相应的 QLineEdit:

connect(checkBox1, SIGNAL(stateChanged(int)), settingsDialog, SLOT(setLineEditEnabled(int)));
connect(checkBox2, SIGNAL(stateChanged(int)), settingsDialog, SLOT(setLineEditEnabled(int)));
connect(checkBox3, SIGNAL(stateChanged(int)), settingsDialog, SLOT(setLineEditEnabled(int)));

当我开始编写 setLineEditEnabled() 函数时,我意识到无法知道哪个 QCheckBox 发送了信号,所以我不知道应该启用哪个 QLineEdit:

void SettingsDialog::setLineEditEnabled(int checkState)
{
    ????->setEnabled(checkState == Qt::Checked);
}

我能想到的唯一解决方案是在对话框类中有一系列函数,每个复选框都有一个:

connect(checkBox1, SIGNAL(stateChanged(int)), settingsDialog, SLOT(setLineEdit1Enabled(int)));
connect(checkBox2, SIGNAL(stateChanged(int)), settingsDialog, SLOT(setLineEdit2Enabled(int)));
connect(checkBox3, SIGNAL(stateChanged(int)), settingsDialog, SLOT(setLineEdit3Enabled(int)));

void SettingsDialog::setLineEdit1Enabled(int checkState)
{
    lineEdit1->setEnabled(checkState == Qt::Checked);
}

void SettingsDialog::setLineEdit2Enabled(int checkState)
{
    lineEdit2->setEnabled(checkState == Qt::Checked);
}

void SettingsDialog::setLineEdit3Enabled(int checkState)
{
    lineEdit3->setEnabled(checkState == Qt::Checked);
}

但是,这似乎有点混乱(实际上有 7 个 QCheckBox-QLineEdit 对,所以我需要 7 个函数),我觉得我错过了一些可以让这更容易的东西。如果我知道哪个对象发送了信号,我可以用一个函数来完成,这样会更整洁。

有没有办法从槽函数中获取发送信号的对象?

如果无法获取信号对象,是否有更好的解决方案,不涉及在对话框类中使用多个函数来启用 QLineEdits?

感谢您的帮助。

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    在这种情况下,您可以使用QCheckBox::toggled(bool) 信号而不是stateChanged(int)。

    connect(checkBox1, SIGNAL(toggled(bool)), lineEdit1, SLOT(setEnabled(bool)));
    connect(checkBox2, SIGNAL(toggled(bool)), lineEdit2, SLOT(setEnabled(bool)));
    connect(checkBox3, SIGNAL(toggled(bool)), lineEdit3, SLOT(setEnabled(bool)));
    

    但是,在槽内,您可以获得发送信号的QObject,调用sender() 方法。见QObject::sender()

    【讨论】:

    • 非常感谢您的帮助。我不知道我怎么找不到 sender() 函数。将来知道这将非常有用。我是 Stack Overflow 的新手,所以我不确定正确的程序。我是编辑我的问题说 [已解决] 还是直接离开?
    【解决方案2】:

    另一种选择是使用 QSignalMapper:

    // Set up a map, just for convenience.
    std::map<QCheckBox*, QLineEdit*> widgetMap;
    widgetMap.emplace(checkBox1, lineEdit1);
    widgetMap.emplace(checkBox2, lineEdit2);
    widgetMap.emplace(checkBox3, lineEdit3);
    
    QSignalMapper signalMapper;
    connect(signalMapper, SIGNAL(mapped(QWidget*)), SLOT(singleSlotHandlingThemAll(QWidget*)));
    
    connect(checkBox1, SIGNAL(statusChanged(int)), signalMapper, SLOT(map()));
    connect(checkBox2, SIGNAL(statusChanged(int)), signalMapper, SLOT(map()));
    connect(checkBox3, SIGNAL(statusChanged(int)), signalMapper, SLOT(map()));
    
    signalMapper->setMapping(checkBox1, checkBox1);
    signalMapper->setMapping(checkBox2, checkBox2);
    signalMapper->setMapping(checkBox3, checkBox3);
    

    这是singleSlotHandlingThemAll() 的实现:

    void singleSlotHandlingThemAll(QWidget* widget)
    {
        // Provided widget is one of the check-boxes.
        QCheckBox* checkBox = static_cast<QCheckBox8>(widget);
    
        QLineEdit* relatedLineEdit = widgetMap[checkBox];
        relatedLineEdit->setEnabled(checkBox->isChecked());
    }
    

    【讨论】:

    • 感谢您提供的信息,这是值得了解的。在这种情况下,使用 toggled(bool) 信号是最简单的解决方案,但将来可能会派上用场。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多