[英]Using sigc::mem_fun by accesing parent of container
我正在嘗試用 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";
}
沒有任何代碼,很難知道您到底在尋找什么。 這是我的做法:我會在網格內保留對父 Window 的引用。 例如:
#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);
}
如果您運行此代碼,您將看到一個窗口,其中包含一個包含一個按鈕的網格。 每當您單擊按鈕時,窗口:
您將在新網格的按鈕標簽上看到更新的計數器值。 在終端中,網格析構函數將打印一條消息,證明網格確實已切換。
請注意,我在這里使用了 lambda 來清理語法。 我建議你也這樣做。 如果您真的想使用sigc::men_fun
,您可以將 lambda 的內容封裝到您在問題中提到的MyGrid::someMethod
方法中。
另請注意,網格是窗口的私有嵌套類(其他人不需要知道...)。
用 GCC 編譯:
g++ main.cpp -o example.out `pkg-config gtkmm-3.0 --cflags --libs`
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.