[英]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.