wxListbook Problem und Stilfrage
-
Hallo,
ich habe ein Probelm mit wxWidgets bzw. Klassen sowie wie eine Stilfrage.
Ich habe vor ein Programm zu schreiben das am linken Rand ein wxListbook hat und im rechten Teil verschiedene Panels anzeigt. Das funktioniert auch fast, nur habe ich das ganze (mMn) etwas 'unschön' umgesetzt.
In der Main werden die Funktionen, die die Panels erzeugen aufgerufen und zum Listbook hinzugefügt. Dann habe ich noch eine Datei namens Caesar, die Funktionen für das Panel enthält, sowie eine Datei globalfuncs, die die globalen Funktionen zum erzuegen der Panels beinhaltet.
So weit so gut, nur stellt sich jetzt die Frage der "Zugriffe", auf dem Panel soll ein Textfeld sowie 2 RadioButtons sein, diese erzeuge ich in der globalen Funktion. Nun habe ich die RadioButtons mit einer Funktion aus der Caesar-Datei verknüpft, welche etwas in das Textfeld schreiben sollte, dies ging 'natürlich' nicht, weil er das Textfeld nicht kennt.
Meine eigentliche Frage ist jetzt wie ich das beheben kann?
Ich könnte zwar alles global schreiben, aber das finde ich eigentlich nicht so gut (außer es gibt keinen anderen Weg).
Zusätzlich bin ich mir auch noch nicht so ganz sicher ob ich überhaupt globale Funktionen benutzen sollte? Vielleicht habt ihr da auch noch ein paar Tipps hinsichtlich Stil für mich wie man das eleganter lösen könnte.Hier der Quellcode:
Main.cpp:#ifdef WX_PRECOMP #include "wx_pch.h" #endif #ifdef __BORLANDC__ #pragma hdrstop #endif //__BORLANDC__ #include "CryptoITMain.h" #include "Caesar.h" #include "globalfuncs.h" CryptoITFrame::CryptoITFrame(wxFrame *frame, const wxString& title) : wxFrame(frame, -1, title) { // Menubar menubar = new wxMenuBar(); // Menu 'Datei' datei = new wxMenu(); // Schliessen datei->Append(wxID_EXIT, wxT("&Beenden\tAlt-F4"), wxT("Beendet die Anwendung")); Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CryptoITFrame::OnMenuFileQuit)); // Menus zur Menubar hinzufuegen menubar->Append(datei, _("&Datei")); SetMenuBar(menubar); // Listbook und Seiten listbook = new wxListbook(this, -1, wxDefaultPosition, wxSize(600, 800), wxNB_FIXEDWIDTH | wxNB_NOPAGETHEME | wxNB_LEFT); window1 = CreatePanelCaesar(listbook); listbook->AddPage(window1, wxT("Caesar"), true); // IDs aus den globalen Funktionen connecten Connect(idBtnTest, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CryptoITFrame::OnMenuFileQuit)); Connect(idRbCrypt, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(Caesar::OnBtnTest)); Center(); } CryptoITFrame::~CryptoITFrame() { } void CryptoITFrame::OnClose(wxCloseEvent& event) { Destroy(); } void CryptoITFrame::OnMenuFileQuit(wxCommandEvent& event) { Destroy(); }
Main.h
#ifndef WX_PRECOMP #include <wx/wx.h> #endif #include <wx/listbook.h> #include "CryptoITApp.h" class CryptoITFrame: public wxFrame { public: CryptoITFrame(wxFrame *frame, const wxString& title); ~CryptoITFrame(); void blub(wxCommandEvent& event); void OnRbDecrypt(wxCommandEvent& event); private: enum{}; wxMenuBar* menubar; wxMenu* datei; wxListbook* listbook; wxPanel* window1; // Caesar Panel void OnClose(wxCloseEvent& event); void OnMenuFileQuit(wxCommandEvent& event); };
Caesar.h
#include <wx/wx.h> #include "CryptoITApp.h" #include "globalfuncs.h" class Caesar: public wxFrame { public: Caesar(); ~Caesar(); void OnBtnTest(wxCommandEvent& event); };
Caesar.cpp
#ifdef WX_PRECOMP #include "wx_pch.h" #endif #ifdef __BORLANDC__ #pragma hdrstop #endif //__BORLANDC__ #include <wx/wx.h> #include "Caesar.h" Caesar::Caesar() { } Caesar::~Caesar() { } void Caesar::OnBtnTest(wxCommandEvent& event) { txtfeld->AppendText(wxT("Test")); }
globalfuncs.cpp
#ifdef WX_PRECOMP #include "wx_pch.h" #endif #ifdef __BORLANDC__ #pragma hdrstop #endif //__BORLANDC__ #include "globalfuncs.h" #include "CryptoITMain.h" #include "Caesar.h" wxPanel* CreatePanelCaesar(wxListbook* parent) { wxPanel* panel = new wxPanel(parent, -1); wxStaticBox* sb = new wxStaticBox(panel, wxID_STATIC, wxT("Auswahl Moeglichkeiten"), wxDefaultPosition, wxSize(-1, -1)); wxRadioButton* rbCrypt = new wxRadioButton(panel, idRbCrypt, wxT("Verschluesseln"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); wxRadioButton* rbDecrypt = new wxRadioButton(panel, idRbCrypt, wxT("Entschluesseln"), wxDefaultPosition, wxDefaultSize); wxTextCtrl* txtfeld = new wxTextCtrl(panel, -1, "" , wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY); wxBoxSizer* bsGes = new wxBoxSizer(wxVERTICAL); wxStaticBoxSizer* sbSizer = new wxStaticBoxSizer(sb, wxHORIZONTAL); wxBoxSizer* hbox = new wxBoxSizer(wxHORIZONTAL); hbox->Add(txtfeld, 1, wxEXPAND); sbSizer->Add(rbCrypt, 1, wxEXPAND); sbSizer->Add(rbDecrypt, 1, wxEXPAND); bsGes->Add(sbSizer, 0, wxEXPAND | wxALL, 10); bsGes->Add(hbox, 0, wxEXPAND | wxALL, 10); panel->SetSizer(bsGes); return panel; }
globalfuncs.h
#ifndef GLOBALFUNCS_H_INCLUDED #define GLOBALFUNCS_H_INCLUDED #include <wx/wx.h> #include <wx/listbook.h> #include "CryptoITApp.h" // IDs enum { idBtnTest = 1000, idRbCrypt, idRbDecrypt }; wxPanel* CreatePanelCaesar(wxListbook* parent);
Die App-Datei hab ich erstmal rausgelassen, da diese imo Standard ist.
Mit freundlichen Grüßen
SickSta
-
Leite die Klasse Caesar von wxPanel ab und ändere den Konstrukur (wie bei CreatePanelCaesar). Im Konstruktor schreibst du auch das erstellen der Controls usw. rein.
Da RadioBtn in Caesar ist geht das connect nicht so wie du es machst.
Mach doch die Event-Funktion und Connect in Caesar (im Konstruktor)
-
Die Idee gefällt mir schon mal sehr gut, war eh nicht so ein Fan von den globalen Funktionen ;-). Wundert mich eigentlich das C++ von A bis Z, das so gemacht hat.
Allerdings hab ich immer noch ein Problem, ich hab jetzt wie du gesagt hast die Controls in den Konstruktor gepackt, und dann noch eine Funktion die das Panel einfach zurück gibt, allerdings haben die Radiobuttons immer noch keine Funktion , ich hab zum Testen noch mal ein richtigen Button hinzugefügt, aber der hat ebenfalls keine Funktion.
Caesar.cpp:#ifdef WX_PRECOMP #include "wx_pch.h" #endif #ifdef __BORLANDC__ #pragma hdrstop #endif //__BORLANDC__ #include <wx/wx.h> #include "Caesar.h" Caesar::Caesar(wxListbook* parent) { panel = new wxPanel(parent, -1); sb = new wxStaticBox(panel, wxID_STATIC, wxT("Auswahl Moeglichkeiten"), wxDefaultPosition, wxSize(-1, -1)); rbCrypt = new wxRadioButton(panel, idBtnTest, wxT("Verschluesseln"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); rbDecrypt = new wxRadioButton(panel, idBtnTest, wxT("Entschluesseln"), wxDefaultPosition, wxDefaultSize); test = new wxButton(panel, idBtnTest, wxT("Test")); txtfeld = new wxTextCtrl(panel, -1, "" , wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY); bsGes = new wxBoxSizer(wxVERTICAL); sbSizer = new wxStaticBoxSizer(sb, wxHORIZONTAL); hbox = new wxBoxSizer(wxHORIZONTAL); hbox->Add(txtfeld, 1, wxEXPAND); sbSizer->Add(rbCrypt, 1, wxEXPAND); sbSizer->Add(rbDecrypt, 1, wxEXPAND); sbSizer->Add(test, 1, wxEXPAND); bsGes->Add(sbSizer, 0, wxEXPAND | wxALL, 10); bsGes->Add(hbox, 0, wxEXPAND | wxALL, 10); panel->SetSizer(bsGes); Connect(idBtnTest, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(Caesar::OnBtnTest)); Connect(idBtnTest, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Caesar::OnBtnTest)); } Caesar::~Caesar() { } void Caesar::OnBtnTest(wxCommandEvent& event) { txtfeld->AppendText(wxT("Test")); } wxPanel* Caesar::CreatePanelCaesar(wxListbook* parent) { return panel; }
Die restlichen Dateien sind eigentlich genauso wie im Startpost, die Caesar.h wurde nur um ein paar Definitionen erweitert.
Hoffe ihr könnt mir dabei auch nochmal helfen.
Vielen Dank erstmal für dies Superidee, werde ich mir auf jeden Fall merken.
SickSta
-
- Caesar unbedingt von wxPanel (nicht wxFrame) ableiten
- Konstruktor von Caesar muss so aussehen:
Caesar::Caesar(wxWindow* parent) :wxPanel(parent) {
Die Zeile entfernen:
panel = new wxPanel(parent, -1);
und da wo panel steht dann immer "this" nehmen
Begründung: Deine Controls sind im Panel und dessen Parent ist Caesar. Die Connect rufst du für Caesar auf, dies hat aber keine Controls (als Childs) sondern hat als Child panel und das hat als Childs die Controls.
-
Juhu es funktioniert
Danke für die super Hilfe und die hilfreiche und verständliche Begründung.Schönen Abend noch
SickSta