如何移动 Gtk::条目光标?



我正在尝试制作一个仅接受数字并将文本显示为货币的自定义Gtk::Entry小部件(gtkmm4)。小数点和千位分隔符会自动添加到文本中。因此,我从Gtk::Entry派生,并将signal_changed()与格式化输入的成员函数连接起来:

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 */
}
};

问题是:用户一次按下一个键,但在特定情况下可以在文本中添加多个符号。似乎光标的默认行为是始终每按下一个键移动 1 个位置,忽略额外的符号。这是结果(|是光标):

结果
当前文本键入的键所需的结果
|(空)10|.010.01|
123.45|61,234.5|61,234.56|
98|0,123.45|79,8|70,123.459,87|0,123.45

该位置似乎没有从条目的处理程序中更新。我尝试了其他处理程序(如insert_text),但出现了同样的问题。解决此问题的一种方法是,从条目的处理程序中,添加一个要在空闲循环中执行的函数。在该函数中,您可以更新位置。这是代码:

#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);
}

这是大小写的简化版本:所有插入的文本都转换为大写,如果可能,光标的位置设置为 2。我认为您可以从中适应您的用例。

相关内容

  • 没有找到相关文章

最新更新