首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Qt 屬性瀏覽器優化:解決 QLineEdit 逐字觸發 valueChanged 的問題

     編輯:關於C語言

Qt 屬性瀏覽器優化:解決 QLineEdit 逐字觸發 valueChanged 的問題

在使用 QtPropertyBrowser (QtPropertyBrowser 2.5) 時,字串屬性對應的編輯器預設為 QLineEdit,其 valueChanged 訊號會在每次按鍵輸入時觸發。對於需要即時預覽、資料庫同步或撤銷/重做機制的編輯器場景,這會造成嚴重的效能問題與邏輯混亂。本文記錄 Ogitor 專案的修改方案:改為編輯完成(Enter 或失焦)才觸發值變更。

問題根因

QtLineEditFactory 原始碼中,直接連接 QLineEdit::textChanged 到內部槽函式,導致每個字元輸入都推送變更。

解決方案:改用 editingFinished 訊號

核心修改點:

  1. 在 QtLineEditFactoryPrivate 新增 slotEditingFinished() 槽函式
  2. 在 createEditor() 中連接 editingFinished() 而非 textChanged()
  3. 槽函式中取得編輯器文字並呼叫 manager->setValue()

關鍵程式碼修改

qteditorfactory.h

class QT_QTPROPERTYBROWSER_EXPORT QtLineEditFactory 
    : public QtAbstractEditorFactory<QtStringPropertyManager>
{
    Q_OBJECT
public:
    // ... 現有介面 ...
private:
    Q_PRIVATE_SLOT(d_func(), void slotEditingFinished())
    // ... 其他槽 ...
};

qteditorfactory.cpp

void QtLineEditFactoryPrivate::slotEditingFinished()
{
    QObject* object = q_ptr->sender();
    const auto ecend = m_editorToProperty.constEnd();
    for (auto it = m_editorToProperty.constBegin(); it != ecend; ++it) {
        if (it.key() == object) {
            QtProperty* property = it.value();
            QtStringPropertyManager* manager = q_ptr->propertyManager(property);
            if (!manager) return;
            
            QString value = static_cast<QLineEdit*>(it.key())->text();
            manager->setValue(property, value);
            return;
        }
    }
}

QWidget* QtLineEditFactory::createEditor(QtStringPropertyManager* manager,
                                         QtProperty* property,
                                         QWidget* parent)
{
    QLineEdit* editor = d_ptr->createEditor(property, parent);
    
    QRegExp regExp = manager->regExp(property);
    if (regExp.isValid()) {
        editor->setValidator(new QRegExpValidator(regExp, editor));
    }
    editor->setText(manager->value(property));

    // 關鍵修改:使用 editingFinished 取代 textChanged
    connect(editor, SIGNAL(editingFinished()),
            this, SLOT(slotEditingFinished()));
    connect(editor, SIGNAL(destroyed(QObject*)),
            this, SLOT(slotEditorDestroyed(QObject*)));
            
    return editor;
}

行為差異對比

觸發時機原始 (textChanged)修改後 (editingFinished)
輸入每個字元觸發不觸發
按下 Enter觸發觸發 ✓
失去焦點觸發觸發 ✓
Esc 取消編輯觸發 (已修改)不觸發 ✓

適用場景與注意事項

  • ✅ 適用:表單編輯、屬性面板、資料庫記錄修改
  • ⚠️ 不適用:即時搜尋建議、字元計數器、即時語法高亮(需保留 textChanged)
  • 🔧 若需同時支援即時預覽與確認提交,可保留兩條訊號連接不同槽函式

總結

透過將 QtLineEditFactory 的訊號連接從 textChanged 改為 editingFinished,僅需修改少量核心程式碼,即可完美解決 Qt 屬性瀏覽器字串編輯器的「逐字觸發」問題,符合大多數編輯器場景的使用直覺與效能需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved