进度条 gtkmm Glade

Posted

技术标签:

【中文标题】进度条 gtkmm Glade【英文标题】:Progress Bar gtkmm Glade 【发布时间】:2021-02-19 13:22:10 【问题描述】:

使用按钮并处理其事件很容易,但我无法与进度条交互。如何从 Glade 文件中获取 Gtk::ProgressBar 并设置其分数?

我使用 Gtkmm 3.24,我想在单击按钮时更新进度条。这是我的空地文件:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
  <requires lib="gtk+" version="3.24"/>
  <object class="GtkApplicationWindow" id="MainWindow">
    <property name="can-focus">False</property>
    <property name="title" translatable="yes">My Main Window</property>
    <property name="default-width">200</property>
    <property name="default-height">150</property>
    <child>
      <object class="GtkBox">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkButton" id="LittleButton">
            <property name="label" translatable="yes">button</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkProgressBar" id="MyProgressBar">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

我的main.cpp 文件

#include <memory>
#include <gtkmm.h>

class MainWindow : public Gtk::ApplicationWindow 

public:
    MainWindow(BaseObjectType* obj, Glib::RefPtr<Gtk::Builder> const& builder)
        : Gtk::ApplicationWindow(obj)
        , builderbuilder
    
        
    
    virtual ~MainWindow() = default;
private:
    Glib::RefPtr<Gtk::Builder> builder;
;

int main(int argc, char* argv[]) 

   auto app = Gtk::Application::create(argc, argv, "de.engelmarkus.example");
   auto builder = Gtk::Builder::create_from_file("MyGladeGUI.glade");
   MainWindow* mwindow = nullptr;
   builder->get_widget_derived("MainWindow", mwindow);
   
   auto littleButton = builder->get_object("LittleButton");
   
   auto r = app->run(*mwindow);
   delete mwindow;

   return r;

我从命令行构建我的应用程序:

g++ -rdynamic main.cpp -o hello $(pkg-config gtkmm-3.0 --libs --cflags)

【问题讨论】:

【参考方案1】:

这里是你想要的代码:

#include <memory>
#include <gtkmm.h>

constexpr int ERROR = 1;

int main(int argc, char* argv[]) 

    auto app = Gtk::Application::create(argc, argv, "de.engelmarkus.example");
    auto builder = Gtk::Builder::create_from_file("MyGladeGUI.glade");

    // Get the window. First a `Glib::Object` handle to it and then cast it
    // to the `Gtk::ApplicationWindow` type:
    Glib::RefPtr<Glib::Object> mainWindowAsObject = builder->get_object("MainWindow");
    Glib::RefPtr<Gtk::ApplicationWindow> mainWindow = Glib::RefPtr<Gtk::ApplicationWindow>::cast_dynamic(mainWindowAsObject);
    if(!mainWindow)
    
        return ERROR;
    
    
    // At this point, the main window is valid, and as bonus, wrapped in a smart
    // pointer, which means you do not have to manage its memory yourself. Now get
    // the button. First get a `Glib::Object` handle to it and then cast it to the
    // `Gtk::Button` type:
    Glib::RefPtr<Glib::Object> buttonAsObject = builder->get_object("LittleButton");
    Glib::RefPtr<Gtk::Button> button = Glib::RefPtr<Gtk::Button>::cast_dynamic(buttonAsObject);
    if(!button)
    
        return ERROR;
    

    // At this point, the button is valid. We have to get the progress bar. You get
    // the idea now ;):
    Glib::RefPtr<Glib::Object> pBarAsObject = builder->get_object("MyProgressBar");
    Glib::RefPtr<Gtk::ProgressBar> pBar = Glib::RefPtr<Gtk::ProgressBar>::cast_dynamic(pBarAsObject);
    if(!pBar)
    
        return ERROR;
    

    // At this point, both the button and the progress bar have been extracted
    // from the builder and are valid. We can now connect the button's 'clicked'
    // signal handler:
    button->signal_clicked().connect([&pBar]()
        const double currentFraction = pBar->get_fraction();
        pBar->set_fraction(currentFraction + 0.10);
    );

    // The syntax is ugly the basically:
    //  1. Call `get()` to retreive the stored pointer
    //  2. Call operator* on this pointer to get a reference
    return app->run(*(mainWindow.get()));

 // mainWindow automatically deleted here by its RefPtr container!

输出:

我冒昧地简化了一点。最重要的是,我审查了您的内存管理模型并完全删除了 delete 的使用,通过使用 Glib::RefPtr 可以为您做到这一点。

您可以使用:

g++ -rdynamic main.cpp -o hello `pkg-config gtkmm-3.0 --libs --cflags`

注意:我是使用 Gtkmm 3.22 编写的。

【讨论】:

感谢您回答我的评论。我无法编译你的代码我在终端中使用这个脚本来构建我的应用程序:g++ -rdynamic main.cpp -o hello $(pkg-config gtkmm-3.0 --libs --cflags) 它给了我很多错误 你能在这里粘贴一些吗?在我的情况下,即使在使用 Gtkmm 3.24 的全新 Ubuntu 安装上也能正常工作。我在答案中添加了工作主窗口的屏幕截图。 这是我的输出日志:logfile 实际上我的代码没有这个问题,这只是针对您的代码。 看来你已经复制了整个东西......甚至是非代码部分。顶部的第一个错误:main.cpp:1:1: error: ‘Here’ does not name a type,对应于我回答的第一个字:“这是执行您想要的操作的代码:”。 没问题,如果我的回答为你解决了,请不要忘记接受。

以上是关于进度条 gtkmm Glade的主要内容,如果未能解决你的问题,请参考以下文章

需要有关 gtkmm 中的多线程的帮助

在 GTK+ 中部分突出显示小部件

请问进度条上方带有文字进度、并且跟随进度条移动的进度条该怎么实现?

C++ 中带有 Gtkmm 的 ProgressBar

android 进度条样式 怎么改

长按如何使进度条变化Android