[英]How to move the Gtk::Entry cursor?
I'm trying to make a custom Gtk::Entry
widget (gtkmm4) that accepts only numbers and shows text as currency.我正在尝试制作一个自定义Gtk::Entry
小部件 (gtkmm4),它只接受数字并将文本显示为货币。 Decimal and thousand separators are automatically added to the text.小数点和千位分隔符会自动添加到文本中。 So I derived from Gtk::Entry
and connected the signal_changed()
with a member function that formats the input:所以我从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 */
}
};
The problem is: the user presses one key at time, but more than one symbol can be added to the text in specific cases.问题是:用户一次按下一个键,但在特定情况下可以向文本添加多个符号。 It seems that the default behavior of the cursor is to always move 1 place per key pressed, ignoring the extra symbols.似乎 cursor 的默认行为是每次按下一个键总是移动 1 个位置,忽略额外的符号。 This is the result ( |
is the cursor):这是结果( |
是光标):
Current Text当前文本 | Typed Key输入键 | Result结果 | Desired Result期望的结果 |
---|---|---|---|
| (empty) (空的) |
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 |
I need to move the cursor to the correct position. At first seemed trivial, but so far I have tried:我需要将 cursor 移动到正确的 position。起初似乎微不足道,但到目前为止我已经尝试过:
Calling set_position(position)
at the end of filterInput()
.在 filterInput() 结束时调用set_position(position)
filterInput()
。
Calling gtk_editable_set_position( GTK_EDITABLE(this->gobj()), position)
at the end of filterInput()
.在 filterInput() 结束时调用gtk_editable_set_position( GTK_EDITABLE(this->gobj()), position)
filterInput()
。
Overriding Entry::on_insert_text(const Glib::ustring& text, int* position)
and change the value pointed by the position
parameter.覆盖Entry::on_insert_text(const Glib::ustring& text, int* position)
并更改position
参数指向的值。
Calling Editable::on_insert_text(const Glib::ustring& text, int* position)
directly at the end of filterInput()
, passing a new position
value.直接在filterInput()
的末尾调用Editable::on_insert_text(const Glib::ustring& text, int* position)
) ,传递一个新的position
值。
Nothing happens.什么都没发生。 All these commands seem to be ignored or ignore the position parameter.所有这些命令似乎都被忽略或忽略了 position 参数。 Am I doing something wrong or is this some kind of bug?我做错了什么还是这是某种错误? How can I set the cursor position correctly in a Gtk::Entry
widget?如何在Gtk::Entry
小部件中正确设置 cursor position?
The position seems not to be updated from the entry's handler. position 似乎没有从条目的处理程序中更新。 I tried other handlers (like insert_text
) and the same issue arises.我尝试了其他处理程序(如insert_text
)并出现了同样的问题。 One way to solve this is to, from within you entry's handler, add a function to be executed in the idle loop.解决此问题的一种方法是,从您的条目处理程序中添加一个 function 以在空闲循环中执行。 In that function, you can update the position. Here is the code:在那个 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);
}
This is a simplified version of you case: all inserted text is transformed to upper case and, if possible, the cursor's position is set to 2. I think you can adapt to your use case from that.这是您案例的简化版本:所有插入的文本都转换为大写,如果可能,光标的 position 设置为 2。我认为您可以从中适应您的用例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.