You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

当QLineEdit派生类处于禁用/只读状态时,如何隐藏操作按钮?

Solution for Hiding Action Button in Disabled/ReadOnly MyEdit

Nice catch on the limitations of overriding setDisabled/setReadOnly (since they're non-virtual) and the missing state change signals you noticed—let's walk through two reliable approaches to solve this:

You might have missed that Qt provides signals for exactly these state changes! QWidget (which QLineEdit inherits from) has an enabledChanged(bool) signal, and QLineEdit itself has a readOnlyChanged(bool) signal. We can hook these up to a helper slot that updates the button's visibility.

First, add a private slot to your MyEdit class declaration:

class MyEdit : public QLineEdit {
    Q_OBJECT
    // ... your existing members ...
private slots:
    void updateButtonVisibility();
};

Then, connect the signals in your constructor, right after setting up your action button:

MyEdit::MyEdit( QWidget *p_parent ) : QLineEdit( p_parent ) {
    // ... your existing initialization code ...
    
    // Connect state change signals to our helper slot
    connect(this, &QWidget::enabledChanged, this, &MyEdit::updateButtonVisibility);
    connect(this, &QLineEdit::readOnlyChanged, this, &MyEdit::updateButtonVisibility);
}

Implement the slot to check all conditions (enabled, not read-only, and has completer data):

void MyEdit::updateButtonVisibility() {
    bool hasValidData = !m_sourceModel->data().isEmpty();
    bool shouldShowButton = isEnabled() && !isReadOnly() && hasValidData;
    m_buttonAction->setVisible(shouldShowButton);
}

Finally, update your setDataForCompleter method to reuse this slot instead of setting visibility directly:

void MyEdit::setDataForCompleter( const CompleterData &p_data ) {
    m_sourceModel->setCompleterData( p_data );
    updateButtonVisibility(); // Let the slot handle visibility logic
}

This approach is clean, follows Qt's signal-slot paradigm, and keeps all visibility logic in one place.

Approach 2: Override event() (For Older Qt Versions)

If you're working with a Qt version before 5.7 (where enabledChanged was added), you can override the event() method to catch state change events directly.

Add this override to your MyEdit class:

class MyEdit : public QLineEdit {
    Q_OBJECT
    // ... your existing members ...
protected:
    bool event(QEvent *event) override;
};

Implement the event() method to handle EnabledChange and ReadOnlyChange events:

bool MyEdit::event(QEvent *event) {
    // Check if we're handling a state change event
    if (event->type() == QEvent::EnabledChange || event->type() == QEvent::ReadOnlyChange) {
        updateButtonVisibility(); // Reuse the same slot from Approach 1!
    }
    // Always pass unhandled events to the parent class
    return QLineEdit::event(event);
}

You can still use the same updateButtonVisibility slot from Approach 1 here—this just gives you a way to trigger it when state changes in older Qt versions.

Bonus: Ensure Initial State is Correct

Don't forget to set the initial visibility of the button in your constructor, right after creating it:

m_buttonAction->setVisible(false); // Start hidden
updateButtonVisibility(); // Check initial state (in case the widget is created disabled/read-only)

内容的提问来源于stack exchange,提问作者songvan

火山引擎 最新活动