簡體   English   中英

如何移動 Gtk::Entry cursor?

[英]How to move the Gtk::Entry cursor?

我正在嘗試制作一個自定義Gtk::Entry小部件 (gtkmm4),它只接受數字並將文本顯示為貨幣。 小數點和千位分隔符會自動添加到文本中。 所以我從Gtk::Entry派生並將signal_changed()與格式化輸入的成員 function 連接起來:

class CurrencyEntry : public Gtk::Entry{

    public:

    CurrencyEntry() {

        set_placeholder_text("0.00");
        connectionChange = signal_changed().connect(
            sigc::mem_fun(*this, &CurrencyEntry::filterInput)
        );      
    }

    protected:

    sigc::connection connectionChange;
    Glib::ustring oldText;

    void filterInput(){

        auto currentText = get_text();

        /* format currentText */

        connectionChange.block();
        set_text(currentText);
        connectionChange.unblock();

        /* move the cursor */
    }

};

問題是:用戶一次按下一個鍵,但在特定情況下可以向文本添加多個符號。 似乎 cursor 的默認行為是每次按下一個鍵總是移動 1 個位置,忽略額外的符號。 這是結果( |是光標):

當前文本 輸入鍵 結果 期望的結果
| (空的) 1 0|.01 0.01|
123.45| 6 1,234.5|6 1,234.56|
98|0,123.45| 7 9,8|70,123.45 9,87|0,123.45

我需要將 cursor 移動到正確的 position。起初似乎微不足道,但到目前為止我已經嘗試過:

  • 在 filterInput() 結束時調用set_position(position) filterInput()

  • 在 filterInput() 結束時調用gtk_editable_set_position( GTK_EDITABLE(this->gobj()), position) filterInput()

  • 覆蓋Entry::on_insert_text(const Glib::ustring& text, int* position)並更改position參數指向的值。

  • 直接在filterInput()的末尾調用Editable::on_insert_text(const Glib::ustring& text, int* position) ) ,傳遞一個新的position值。

什么都沒發生。 所有這些命令似乎都被忽略或忽略了 position 參數。 我做錯了什么還是這是某種錯誤? 如何在Gtk::Entry小部件中正確設置 cursor position?

position 似乎沒有從條目的處理程序中更新。 我嘗試了其他處理程序(如insert_text )並出現了同樣的問題。 解決此問題的一種方法是,從您的條目處理程序中添加一個 function 以在空閑循環中執行。 在那個 function 中,您可以更新 position。這是代碼:

#include <algorithm>
#include <iostream>
#include <string>

#include <gtkmm.h>

class CurrencyEntry : public Gtk::Entry
{

public:

    CurrencyEntry()
    {
        m_connection = signal_changed().connect(
        [this]()
        {
            // Get the current edit box content:
            std::string str = get_text();

                // Make it upper case:
                std::transform(str.begin(), str.end(), str.begin(), ::toupper);

                // Set the updated text. The connection is blocked to avoid
                // recursion:
                m_connection.block();
                set_text(str);
                m_connection.unblock();

                // Update the position in the idle loop:
                Glib::signal_idle().connect(
                [this]()
                {
                    set_position(2);
                    return false;
                });
        });
    }

private:

    sigc::connection m_connection;
};

class MainWindow : public Gtk::ApplicationWindow
{

public:

    MainWindow();

private:

    CurrencyEntry m_entry;

};

MainWindow::MainWindow()
{
    add(m_entry);
}

int main(int argc, char *argv[])
{
    auto app = Gtk::Application::create(argc, argv, "org.gtkmm.examples.base");
  
    MainWindow window;
    window.show_all();
  
    return app->run(window);
}

這是您案例的簡化版本:所有插入的文本都轉換為大寫,如果可能,光標的 position 設置為 2。我認為您可以從中適應您的用例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM