前言
- 在之前的打包测试中我提到了需要一个挑选dll的程序
- 于是我打算用Gtk来制作这个程序
预览
细节要点
初始窗口尺寸
- 只有主窗口有set_default_size()方法, 控件没有这个方法
- 我发现Gtk的初始窗口大小和最小窗口大小限制 集合在同一个方法内:
set_size_request() - 这就有问题了, 我需要程序(控件)一开始呈现足够可观的尺寸, 但不是最小只能是这个尺寸, 我希望后续能够调小
- 于是我发现了size_allocate_vfunc这个虚函数,
只要有窗口尺寸发生变化的事件一触发就会调用这个函数
我们可override一下主窗口的这个虚函数, 在里面做你需要做的事
那么上面的问题我只需再次set_size_request()便可解决 - std::call_once函数可帮助我在整个程序生命期里只执行一次,虽然自己写一个bool判断也可以达成目的, 但std::call_once更方便可观, 而且用了mutex, 是线程安全的
void size_allocate_vfunc(int width, int height, int baseline)override { std::cout << width << " " << height << " " << baseline << " " << std::endl; Gtk::Widget::size_allocate_vfunc(width, height, baseline); m_pMainPaned->set_position(width - 100);//设置第二个Paned的滑动柄位置 m_pSubPaned->set_position(100);//设置第一个Paned的滑动柄位置 std::call_once(onceFlag, [this] { m_pMBox->set_size_request(100, 100); }); }
- 上面也设置了split窗口滑动柄位置也随着主窗口尺寸变化
提示音
- 我发现不能像以前那样printf(“%c”,7);来发出蜂鸣器Beep~的声音
- 于是我发现了
Beep()的声音不太好听//Beep(1000, 150); windows平台 需包含<windows.h> //gdk_surface_beep(this->get_surface()->gobj());//通用 gdk_display_beep(this->get_display()->gobj());//通用
快速提示信息对话框AlertDialog
void ExampleWindow::Hints(std::string Message, const std::function<void()> &callable) {
auto tempDialog = Gtk::AlertDialog::create();
// Reset values that may have been set by on_button_question_clicked().
tempDialog->set_modal(true);
tempDialog->set_message("提示.");
tempDialog->set_detail(Message);
tempDialog->set_buttons({"OK"});
tempDialog->set_default_button(0); // OK button or Return key
tempDialog->set_cancel_button(0); // Cancel button or Escape key
tempDialog->choose(*this, [callable](const Glib::RefPtr<Gio::AsyncResult> &result) {
if (callable) {
callable();
}
});
gdk_display_beep(this->get_display()->gobj());
}
鼠标移入移出事件
- https://gnome.pages.gitlab.gnome.org/gtkmm-documentation/sec-eventsignals.html
- 如果只是简单的点击事件那就不需要关心事件控制器
- 但比如要鼠标移入时模糊
void BG_blur() { auto controrller = Gtk::EventControllerMotion::create(); controrller->signal_enter().connect([this](const double &a, const double &b) { std::cout << "enter" << std::endl; auto style = m_pBG_image->get_style_context(); style->add_class("hovered"); }, true); controrller->signal_leave().connect([this]() { std::cout << "leave" << std::endl; auto style = m_pBG_image->get_style_context(); style->remove_class("hovered"); }, true); m_pmainFrame->add_controller(controrller); };
布局与父子控件关系
-
一般兄弟控件之间各占一块空间, 有些时候需要有能重叠的控件
-
比如我需要给程序做背景图片怎么办?
给父控件添加css属性background-image: url(‘xxx.png’);
?
可以是可以, 但我一旦给它的图片加了一些css的动画效果, 会影响到它全部的子控件, 比如filter: blur(5px);
-
于是 Gtk::Overlay 被我找出来了
有两个方法 set_child(A) 和add_overlay(B) 用来做重叠关系
B总叠在A上面前需:
A和B都不能有 parent 否则set_child 和 add_overlay 都将失败Cambalache中也直接提供 Gtk::Overlay 控件
只需要把 B 放到它的下级目录就不用担心 B 有 parent
A也同理
也可以在 Cambalache 中设置她的子控件这样就不用在.cpp文件中再set_child()了:
只需要把它下级目录下某一个控件的id填入其中即可
使其成为该overlay控件下 重叠顺序中最底层的控件
图片
- 使用css背景图片是真方便
background-image: url('GoolGirl2.png'); background-position: right center; background-size: cover;
- 但有时候要获取图片的原始尺寸做一些定制操作时就不那么方便了
后续
- 还有一些gtk的控件我没有太深的了解
- 搜索功能已完成
- ctrl+f 可搜索 ldd打印出来的未命中的dll的上下文