如何将小部件和数据从一个文件传递到不同类中的另一个文件?

发布于 2025-02-10 23:58:41 字数 3298 浏览 1 评论 0 原文

初学者级问题。我正在创建一个计数器应用程序(第一个应用程序来自 7个任务)。我在一个文件中创建了此应用程序,并且工作正常。以下是代码。

class Application : Gtk.Application {
  public int val = 0;

  public Application() {
    Object(
      application_id: "com.github.uname.counter",
      flags: ApplicationFlags.FLAGS_NONE
    );
  }
  
  protected override void activate() {
    var window = new Gtk.ApplicationWindow(this);
    window.default_height = 30;
    window.default_width = 300;
    window.title = "Counter";
    
    var grid = new Gtk.Grid();
    grid.column_homogeneous = true;
    grid.row_homogeneous = true;
    grid.row_spacing = 5;
    grid.column_spacing = 5;
    
    var entry = new Gtk.Entry();
    entry.text = val.to_string();
    entry.editable = false;
    grid.attach(entry, 0, 0, 1, 1);

    var button1 = new Gtk.Button.with_label("Counter");
    grid.attach(button1, 1, 0, 1, 1);
    
    button1.clicked.connect (() => {
      this.val = this.val + 1;
      entry.text = this.val.to_string();
    });

    window.add(grid);
    window.show_all();
  }
  
  public static int main(string[] args) {
    var application = new Application();
    return application.run(args);
  }
}

现在,我正在尝试将上述代码分为单独的文件,例如 application.vala entry> entry.vala button.vala 。这是这些文件的代码。

application.vala 的代码。

class Application : Gtk.Application {
  public int val = 0;

  public Application() {
    Object(
      application_id: "com.github.chauhankiran.counter",
      flags: ApplicationFlags.FLAGS_NONE
    );
  }
  
  protected override void activate() {
    var window = new Gtk.ApplicationWindow(this);
    window.default_height = 30;
    window.default_width = 300;
    window.title = "Counter";
    
    var grid = new Gtk.Grid();
    grid.column_homogeneous = true;
    grid.row_homogeneous = true;
    grid.row_spacing = 5;
    grid.column_spacing = 5;
    
    var entry = new Entry(val);
    grid.attach(entry, 0, 0, 1, 1);

    var button1 = new Button(val);
    grid.attach(button1, 1, 0, 1, 1);

    window.add(grid);
    window.show_all();
  }
  
  public static int main(string[] args) {
    var application = new Application();
    return application.run(args);
  }
}

entry.vala 的代码。

public class Entry : Gtk.Entry {
  public Entry(int val) {
    text = val.to_string();
  }

  construct {
    editable = false;
  }
}

button.vala 的代码。

public class Button : Gtk.Button {
  // Is it correct?
  public int val;

  public Button(int val) {
    this.val = val;
  }

  construct {
    label = "Counter";
  }

  // How to write this within Button.vala from Application.vala?
  // How to get entry widget in this class?
  button1.clicked.connect (() => {
    this.val = this.val + 1;
    entry.text = this.val.to_string();
  });
}

现在,我有以下问题。

  1. entry.vala 接受 val 作为初始值。我不知道如何通过构造传递它。因此,我使用了公共对象方法。是正确的方式吗?
  2. button.vala 中,我还需要val以及对条目的访问,以便我可以访问button.vala中的条目?还是这是执行代码的不正确方法?如果是这样,请建议正确的方式。当前分开的文件代码会引发错误,因为我不知道如何正确连接和传递信息。

Beginner-level questions. I’m creating a counter application (first application from The 7 Tasks). I created this application in one file and it is working fine. Following is the code.

class Application : Gtk.Application {
  public int val = 0;

  public Application() {
    Object(
      application_id: "com.github.uname.counter",
      flags: ApplicationFlags.FLAGS_NONE
    );
  }
  
  protected override void activate() {
    var window = new Gtk.ApplicationWindow(this);
    window.default_height = 30;
    window.default_width = 300;
    window.title = "Counter";
    
    var grid = new Gtk.Grid();
    grid.column_homogeneous = true;
    grid.row_homogeneous = true;
    grid.row_spacing = 5;
    grid.column_spacing = 5;
    
    var entry = new Gtk.Entry();
    entry.text = val.to_string();
    entry.editable = false;
    grid.attach(entry, 0, 0, 1, 1);

    var button1 = new Gtk.Button.with_label("Counter");
    grid.attach(button1, 1, 0, 1, 1);
    
    button1.clicked.connect (() => {
      this.val = this.val + 1;
      entry.text = this.val.to_string();
    });

    window.add(grid);
    window.show_all();
  }
  
  public static int main(string[] args) {
    var application = new Application();
    return application.run(args);
  }
}

Now, I'm trying to divide the above code into separate files such as Application.vala, Entry.vala, and Button.vala. Here is the code for these files.

Code for Application.vala.

class Application : Gtk.Application {
  public int val = 0;

  public Application() {
    Object(
      application_id: "com.github.chauhankiran.counter",
      flags: ApplicationFlags.FLAGS_NONE
    );
  }
  
  protected override void activate() {
    var window = new Gtk.ApplicationWindow(this);
    window.default_height = 30;
    window.default_width = 300;
    window.title = "Counter";
    
    var grid = new Gtk.Grid();
    grid.column_homogeneous = true;
    grid.row_homogeneous = true;
    grid.row_spacing = 5;
    grid.column_spacing = 5;
    
    var entry = new Entry(val);
    grid.attach(entry, 0, 0, 1, 1);

    var button1 = new Button(val);
    grid.attach(button1, 1, 0, 1, 1);

    window.add(grid);
    window.show_all();
  }
  
  public static int main(string[] args) {
    var application = new Application();
    return application.run(args);
  }
}

Code for Entry.vala.

public class Entry : Gtk.Entry {
  public Entry(int val) {
    text = val.to_string();
  }

  construct {
    editable = false;
  }
}

Code for Button.vala.

public class Button : Gtk.Button {
  // Is it correct?
  public int val;

  public Button(int val) {
    this.val = val;
  }

  construct {
    label = "Counter";
  }

  // How to write this within Button.vala from Application.vala?
  // How to get entry widget in this class?
  button1.clicked.connect (() => {
    this.val = this.val + 1;
    entry.text = this.val.to_string();
  });
}

Now, I have the following questions.

  1. Entry.vala accepts val as initial value. I don't know how to pass it in construct. So, I used public object method. Is it correct way?
  2. In Button.vala I need val as well access to entry so that I can get access to entry in Button.vala? Or this is incorrect way to do the code? If that is that is the case, please suggest correct way. Currently separate files code throws error as I don’t know how to connect and pass the information correctly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜柠檬 2025-02-17 23:58:41

这7个任务是学习的好练习,您似乎已经取得了一个愉快的开端!

  1. entry.Vala接受Val作为初始值。我不知道如何在构造中传递它。因此,我使用了公共对象方法。这是正确的方式吗?

处理Vala构造的首选方法是使用GoBject-Style构造:

您正在做的事情在技术上可以使用,但是使用Gobject-style,您最终会得到以下内容

public class Entry : Gtk.Entry {
  public Entry(int val) {
    Object (
      text: val.to_string(),
      editable: false
    );
  }
}

:请注意:

  1. 这仅适用于 properties 被声明为 code> construct> construct> /code>或 set
  2. 语法与您所做的略有不同(属性:value vs. member = value

和其他小小优化:

  • Edialtial 也是可以在构造函数中设置的属性,因此在此处无需构造 block!

请注意,您也可以对按钮类进行一些类似的更改!

  1. 在button.vala中,我还需要瓦尔进入入口,以便我可以得到
    访问输入button.vala?否则这是做不正确的方法
    代码?如果是这样,请建议正确的方式。
    当前单独的文件代码会引发错误,因为我不知道如何
    连接并正确传递信息。

当前,您的按钮代码中有对条目的引用。我会从面向对象的编程(OOP)的角度来建议不要这样做(您可能会听到人们以

...
var entry = new Entry(val);
grid.attach(entry, 0, 0, 1, 1);

var button1 = new Button(val);
grid.attach(button1, 1, 0, 1, 1);

button1.clicked.connect (() => {
  // Update the entry
});
...

让我们快速查看您的按钮:

public class Button : Gtk.Button {
  // Is it correct?
  public int val;
  ...

不是错误,在那里是做自己正在做的多种方法。因此,让我们按原样滚动。

此时,您已经拥有您的按钮,每次点击时都会更新内部 int 值,现在您需要更新条目以显示新值。当前您有:

button1.clicked.connect (() => {
  this.val = this.val + 1;
  entry.text = this.val.to_string();
});

由于现在在 application 类中进行处理,因此您需要将这些引用更改为 this ,因为您要引用并更新 val 从按钮中,而不是您用于初始值的应用程序中的变量:

button1.clicked.connect (() => {
  button1.val = button1.val + 1;
  entry.text = button1.val.to_string();
});

希望有所帮助,您将其分为多个的方式是99%课!保持它,并在下一个任务中祝你好运!

The 7 Tasks are a good exercise to learn, and you seem to be off to a great start!

  1. Entry.vala accepts val as initial value. I don't know how to pass it in construct. So, I used public object method. Is it correct way?

The preferred way to handle construction in Vala is using GObject-style construction: https://wiki.gnome.org/Projects/Vala/Tutorial#GObject-Style_Construction

What you're doing would technically work, but using the GObject-style you'd end up with something like the following:

public class Entry : Gtk.Entry {
  public Entry(int val) {
    Object (
      text: val.to_string(),
      editable: false
    );
  }
}

The important things to note here are:

  1. This only works for properties declared as construct or set
  2. The syntax is slightly different than what you were doing (property: value vs. member = value)

And one other little optimization:

  • editable is also a property that can be set in the constructor, so no need for a construct block here!

Notice that you can make some similar changes to your Button class as well!

  1. In Button.vala I need val as well access to entry so that I can get
    access to entry in Button.vala? Or this is incorrect way to do the
    code? If that is that is the case, please suggest correct way.
    Currently separate files code throws error as I don’t know how to
    connect and pass the information correctly.

Currently your Button code has references to the Entry in it. I would advise against this from an object-oriented programming (OOP) perspective (you may hear people toss around terms like Single-Responsibility or Separation of Concerns, etc.), but the gist is that the button should just focus on being what it is: a button. A button doesn't need to be aware of the presence of the entry, and the entry doesn't need to exist in order to have a button. Your logic of handling what happens between widgets when the button is clicked should happen at a level above. In this case, that would be in your Application class where you've created both of those widgets:

...
var entry = new Entry(val);
grid.attach(entry, 0, 0, 1, 1);

var button1 = new Button(val);
grid.attach(button1, 1, 0, 1, 1);

button1.clicked.connect (() => {
  // Update the entry
});
...

Let's take a quick look at your button:

public class Button : Gtk.Button {
  // Is it correct?
  public int val;
  ...

It's not wrong, and there are many ways to do what you're doing. So let's roll with it as is.

At this point you've got your button which updates an internal int value every time it's clicked and you now need to update the entry to display the new value. Currently you have:

button1.clicked.connect (() => {
  this.val = this.val + 1;
  entry.text = this.val.to_string();
});

Since this is now being handled in the Application class, you'll need to change those references to this, since you want to reference and update val from the button, not the variable in Application that you're using for the initial value:

button1.clicked.connect (() => {
  button1.val = button1.val + 1;
  entry.text = button1.val.to_string();
});

Hopefully that helped a bit, you were 99% of the way there with splitting it into multiple classes! Keep it up, and good luck on the next tasks!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文