gpt4 book ai didi

c++ - 通过访问容器的父级来使用 sigc::mem_fun

转载 作者:行者123 更新时间:2023-12-03 07:02:03 28 4
gpt4 key购买 nike

我正在尝试用 Gtkmm3 制作一个简单的软件。
我想要一个里面有网格的窗口。单击该网格内的按钮时,应触发窗口的一种方法以删除当前网格并将其替换为另一个网格。
我可以使用这样的网格方法:

button.signal_clicked().connect(sigc::mem_fun(*this, &MyGrid::someMethod));
“这个”是 MyGrid。
我想做这样的事情:
button.signal_clicked().connect(sigc::mem_fun(*this->get_parent(), &MyWindow::someMethod));
其中 this->get_parent() 将是 MyWindow 的一个实例
我的.h:

#ifndef MINIPROJECT_GUI_H
#define MINIPROJECT_GUI_H

#include <gtkmm/button.h>
#include <gtkmm/window.h>
#include <gtkmm/grid.h>
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <gtkmm/label.h>


class WelcomeGrid: public Gtk::Grid
{
Gtk::Label message;
Gtk::Button nextButton; // This button should be connected to Fenetre::infoView()
public:
WelcomeGrid();
void display();

};


class InfoGrid : public Gtk::Grid
{
Gtk::Button button2;// This button should be connected to Fenetre::welcomeView()
Gtk::Label label2;
public:
InfoGrid();
void display();
};


class Fenetre : public Gtk::Window
{

public:
Fenetre();
virtual ~Fenetre(); // Setup window

void welcomeView();

protected:
//Member widgets:
WelcomeGrid welcome;
InfoGrid info;
void infoView(); // Remove the current grid from the window and replace it by infoGrid
void welcomeView(); // Remove the current grid from the window and replace it by WelcomeGrid

};


#endif //MINIPROJECT_GUI_H
我的 .cpp :
#include "GUI.h"

Fenetre::Fenetre()
{
// Sets the border width of the window.
set_border_width(10);
this->add(welcome);
}

Fenetre::~Fenetre()
{
}

void Fenetre::welcomeView() {
this->remove();
this->add(welcome);
}

void Fenetre::infoView() {
this->remove();
this->add(info);
}


InfoGrid::InfoGrid() {
button2.set_label("Hello.");
button2.signal_clicked().connect(sigc::mem_fun(*this,
&InfoGrid::display));

label2.set_label("Welcome on the Vampire creation interface.");
this->attach(label2, 0, 0, 1, 1);
this->attach(button2,1,1,1,1);
button2.show();
this->show_all();
}



WelcomeGrid::WelcomeGrid() {
nextButton.set_label("Create new character.");
auto a = this->get_parent();
nextButton.signal_clicked().connect(sigc::mem_fun(*this,
&WelcomeGrid::display));

message.set_label("Welcome on the Vampire creation interface.");
this->attach(message, 0, 0, 1, 1);
this->attach(nextButton,1,1,1,1);
// This packs the button into the Window (a container);
this->show_all();
}

void WelcomeGrid::display() {
auto a = this->get_parent();
std::cout << typeid(a).name();
}

void InfoGrid::display() {
std::cout << "coucou";
}

最佳答案

没有任何代码,很难知道您到底在寻找什么。我会这样做:我会在网格内保留对父窗口的引用。例如:

#include <iostream>
#include <memory>
#include <sstream>

#include <gtkmm.h>

class MyWindow : public Gtk::Window
{

public:

MyWindow()
: m_grid{std::make_unique<MyGrid>(*this, m_count)}
{
add(*m_grid);
}

// This is called when the grid's button is pressed:
void ReplaceGrid()
{
++m_count;

// Remove the grid from the window:
remove();

// Destroy current grid:
m_grid = nullptr;

// Create a new grid:
m_grid = std::make_unique<MyGrid>(*this, m_count);

// Add it to the window:
add(*m_grid);

show_all();
}

private:

class MyGrid : public Gtk::Grid
{

public:

MyGrid(MyWindow& p_parent, int p_count)
: m_parent{p_parent}
{
// Create button:
std::ostringstream ss;
ss << "Replace me #" << p_count;
m_replaceButton = Gtk::Button(ss.str());

// Attach it to the grid:
attach(m_replaceButton, 0, 0, 1, 1);

// Connect replacement signal, using the parent window:
m_replaceButton.signal_clicked().connect([this]()
{
// Call the parent (the window):
m_parent.ReplaceGrid();
});
}

~MyGrid()
{
std::cout << "Grid destroyed" << std::endl;
}

private:

Gtk::Button m_replaceButton;

// Keep a reference to the parent window in the grid:
MyWindow& m_parent;
};

int m_count = 0;
std::unique_ptr<MyGrid> m_grid;
};

int main(int argc, char *argv[])
{
auto app = Gtk::Application::create(argc, argv, "so.question.q64594709");
MyWindow w;

w.show_all();

return app->run(w);
}
如果您运行此代码,您将看到一个带有一个包含一个按钮的网格的窗口。每当您单击按钮时,窗口:
  • 更新计数器
  • 破坏当前网格
  • 使用更新后的计数器值
  • 创建一个新网格

    您将在新网格的按钮标签上看到更新的计数器值。在终端中,grids 析构函数将打印一条消息,证明 grids 确实被切换了。
    请注意,我在这里使用了 lambdas 来清理语法。我建议你也这样做。如果你真的想用 sigc::men_fun ,您可以将 lambda 的内容封装到 MyGrid::someMethod您在问题中提到的方法。
    另请注意,网格是窗口的私有(private)嵌套类(没有其他人需要知道......)。
    使用 GCC 编译:
    g++ main.cpp -o example.out `pkg-config gtkmm-3.0 --cflags --libs`

    关于c++ - 通过访问容器的父级来使用 sigc::mem_fun,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64594709/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com