Appunti di informatica by Carlo

facileEsempio di programma C++ con librerie wxWidgets

gif(Aggiornamento dell'articolo al 27/10/2024)

wxWidgets

Ora che avete compilato la libreria wxWidgets e scaricato il materiale per compilare i programmi con tale libreria, potete provare questo programma in C++ con wxWidgets.
Il programma si chiama "Rettangolo" e serve per calcolare appunto perimetro e area di tale figura geometrica; in questa pagina vi sono i codici sorgenti.
Si presenta come la figura a destra, per chi usa il computer o sopra, per chi usa lo smartphone.
Se si possiede un computer con uno schermo ad alta risoluzione (4K o superiore), è opportuno aggiungere nella cartella dei sorgenti anche il file di risorse "rettangolo.rc":


// rettangolo.rc
// APPLICAZIONE Rettangolo
// di Carlo Sala
// 05/09/2024
//
#define wxUSE_NO_MANIFEST 0
#define wxUSE_DPI_AWARE_MANIFEST 2
#if !defined(__llvm__)
#include "wx/msw/wx.rc"
#endif

Codici sorgentiScarica qui!


///////////////////////////////////////////////////////////////////////////
// Name: gui.cpp
// C++ code generated with wxFormBuilder (version Nov  5 2013)
// http://www.wxformbuilder.org/
// Author: Sala Carlo - 05/09/2024
///////////////////////////////////////////////////////////////////////////
#include "gui.h"
///////////////////////////////////////////////////////////////////////////
MainFrameBase::MainFrameBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
{
	wxArrayString includeList;
	includeList.Add(wxT("0"));
	includeList.Add(wxT("1"));
	includeList.Add(wxT("2"));
	includeList.Add(wxT("3"));
	includeList.Add(wxT("4"));
	includeList.Add(wxT("5"));
	includeList.Add(wxT("6"));
	includeList.Add(wxT("7"));
	includeList.Add(wxT("8"));
	includeList.Add(wxT("9"));
	wxTextValidator textValidator(wxFILTER_INCLUDE_CHAR_LIST);
	textValidator.SetIncludes(includeList);
	this->SetSize(FromDIP(wxSize (400,355)));
	this->SetSizeHints( wxDefaultSize, wxDefaultSize );
	this->SetBackgroundColour( wxColour( 180, 180, 180 ) );
	wxBoxSizer* bSizer1;
	bSizer1 = new wxBoxSizer( wxVERTICAL );
	m_panel1 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	wxBoxSizer* bSizer2;
	bSizer2 = new wxBoxSizer( wxVERTICAL );
	wxBoxSizer* bSizer3;
	bSizer3 = new wxBoxSizer( wxVERTICAL );
	m_staticText1 = new wxStaticText( m_panel1, wxID_ANY, _T("Area e perimetro del rettangolo"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
	m_staticText1->Wrap( -1 );
	m_staticText1->SetFont(wxFontInfo(16).FaceName("Arial").Italic().Bold());
	m_staticText1->SetForegroundColour( wxColour( 32, 54, 210 ) );
	bSizer3->Add( m_staticText1, 0, wxALL|wxEXPAND|wxLEFT|wxRIGHT, 5 );
	m_staticText2 = new wxStaticText( m_panel1, wxID_ANY, _T("(Possibilità di inserire anche i decimali !!)"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
	m_staticText2->Wrap( -1 );
	m_staticText2->SetFont(wxFontInfo(9).FaceName("Arial").Italic().Bold());
	bSizer3->Add( m_staticText2, 0, wxALL|wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
	bSizer2->Add( bSizer3, 1, wxEXPAND, 5 );
	bSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
	wxBoxSizer* bSizer4;
	bSizer4 = new wxBoxSizer( wxHORIZONTAL );
	m_staticText3 = new wxStaticText( m_panel1, wxID_ANY, _T("Base:"), wxDefaultPosition, FromDIP(wxSize(122, -1)), 0 );
	m_staticText3->Wrap( -1 );
	m_staticText3->SetFont(wxFontInfo(9).FaceName("Arial"));
	bSizer4->Add( m_staticText3, 0, wxALL, 5 );
	m_textCtrl1 = new wxTextCtrl( m_panel1, wxID_ANY, wxEmptyString, wxDefaultPosition, FromDIP(wxSize(60, -1)), 0|wxWANTS_CHARS,textValidator );
	m_textCtrl1->SetMaxLength( 3 );
	m_textCtrl1->SetFont(wxFontInfo(9).FaceName("Arial").Bold());
	bSizer4->Add( m_textCtrl1, 0, wxEXPAND, 5 );
	m_staticText4 = new wxStaticText( m_panel1, wxID_ANY, _(","), wxDefaultPosition, wxDefaultSize, 0 );
	m_staticText4->Wrap( -1 );
	m_staticText4->SetFont(wxFontInfo(9).FaceName("Arial"));
	bSizer4->Add( m_staticText4, 0, wxALL, 5 );
	m_textCtrl2 = new wxTextCtrl( m_panel1, wxID_ANY, wxEmptyString, wxDefaultPosition, FromDIP(wxSize(35, -1)), 0|wxWANTS_CHARS,textValidator );
	m_textCtrl2->SetMaxLength( 2 ); 
	m_textCtrl2->SetFont(wxFontInfo(9).FaceName("Arial").Bold());	
	bSizer4->Add( m_textCtrl2, 0, wxEXPAND, 5 );
	bSizer2->Add( bSizer4, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 );
	wxBoxSizer* bSizer6;
	bSizer6 = new wxBoxSizer( wxHORIZONTAL );
	m_staticText5 = new wxStaticText( m_panel1, wxID_ANY, _T("Altezza:"), wxDefaultPosition, FromDIP(wxSize(122, -1)), 0 );
	m_staticText5->Wrap( -1 );
	m_staticText5->SetFont(wxFontInfo(9).FaceName("Arial"));
	bSizer6->Add( m_staticText5, 0, wxALL, 5 );
	m_textCtrl3 = new wxTextCtrl( m_panel1, wxID_ANY, wxEmptyString, wxDefaultPosition, FromDIP(wxSize(60, -1)), 0|wxWANTS_CHARS,textValidator );
	m_textCtrl3->SetMaxLength( 3 ); 
	m_textCtrl3->SetFont(wxFontInfo(9).FaceName("Arial").Bold());	
	bSizer6->Add( m_textCtrl3, 0, wxEXPAND, 5 );
	m_staticText6 = new wxStaticText( m_panel1, wxID_ANY, _(","), wxDefaultPosition, wxDefaultSize, 0 );
	m_staticText6->Wrap( -1 );
	m_staticText6->SetFont(wxFontInfo(9).FaceName("Arial"));
	bSizer6->Add( m_staticText6, 0, wxALL, 5 );
	m_textCtrl4 = new wxTextCtrl( m_panel1, wxID_ANY, wxEmptyString, wxDefaultPosition, FromDIP(wxSize(35, -1)), 0|wxWANTS_CHARS,textValidator );
	m_textCtrl4->SetMaxLength( 2 );
	m_textCtrl4->SetFont(wxFontInfo(9).FaceName("Arial").Bold());
	bSizer6->Add( m_textCtrl4, 0, wxEXPAND, 5 );
	bSizer2->Add( bSizer6, 0, wxBOTTOM|wxEXPAND, 5 );
	bSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
	wxBoxSizer* bSizer7;
	bSizer7 = new wxBoxSizer( wxHORIZONTAL );
	m_button1 = new wxButton( m_panel1, wxID_ANY, _T("Calcola !!"), wxDefaultPosition, FromDIP(wxSize(122, -1)), 0 );
	bSizer7->Add( m_button1, 0, wxLEFT, 5 );
	bSizer2->Add( bSizer7, 0, wxTOP|wxBOTTOM|wxEXPAND, 5 );
	bSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
	wxBoxSizer* bSizer8;
	bSizer8 = new wxBoxSizer( wxHORIZONTAL );
	m_staticText7 = new wxStaticText( m_panel1, wxID_ANY, _T("Area del rettangolo:"), wxDefaultPosition, FromDIP(wxSize(258, -1)), 0 );
	m_staticText7->Wrap( -1 );
	m_staticText7->SetFont(wxFontInfo(9).FaceName("Arial"));
	bSizer8->Add( m_staticText7, 0, wxLEFT, 5 );
	m_staticText8 = new wxStaticText( m_panel1, wxID_ANY, wxEmptyString, wxDefaultPosition, FromDIP(wxSize(142, -1)), 0);
	m_staticText8->Wrap( -1 );
	m_staticText8->SetFont(wxFontInfo(12).FaceName("Arial").Bold());
	m_staticText8->SetForegroundColour(wxColour(3,7,253));
	m_staticText8->SetBackgroundColour( wxColour( 251, 220, 108 ) );
	bSizer8->Add( m_staticText8, 0, wxRIGHT, 5 );
	bSizer2->Add( bSizer8, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
	wxBoxSizer* bSizer9;
	bSizer9 = new wxBoxSizer( wxHORIZONTAL );
	m_staticText9 = new wxStaticText( m_panel1, wxID_ANY, _T("Perimetro del rettangolo:"), wxDefaultPosition, FromDIP(wxSize(258, -1)), 0 );
	m_staticText9->SetFont(wxFontInfo(9).FaceName("Arial"));
	m_staticText9->Wrap( -1 );
	bSizer9->Add( m_staticText9, 0, wxLEFT, 5 );
	m_staticText10 = new wxStaticText( m_panel1, wxID_ANY, wxEmptyString, wxDefaultPosition, FromDIP(wxSize(142, -1)), 0);
	m_staticText10->Wrap( -1 );
	m_staticText10->SetFont(wxFontInfo(12).FaceName("Arial").Bold());
	m_staticText10->SetForegroundColour( wxColour(3,7,253));
	m_staticText10->SetBackgroundColour( wxColour( 251, 220, 108 ) );
	bSizer9->Add( m_staticText10, 0, wxRIGHT, 5 );
	bSizer2->Add( bSizer9, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
	bSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
	wxBoxSizer* bSizer10;
	bSizer10 = new wxBoxSizer( wxVERTICAL );
	bSizer10->Add( 0, 0, 1, wxEXPAND, 5 );
	m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY );
	m_hyperlink1 = new wxGenericHyperlinkCtrl( m_panel1, wxID_ANY, _T("© Carlo Sala software"), wxT("https://www.carlosala.net/"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE );
	m_statusBar->PushStatusText(" V.: 1.0.0"); 
	m_hyperlink1->SetHoverColour( wxColour( 32, 54, 210 ) );
	m_hyperlink1->SetNormalColour( wxColour( 64, 64, 64 ) );
	m_hyperlink1->SetVisitedColour( wxColour( 64, 64, 64 ) );
	bSizer10->Add( m_hyperlink1, 0, wxALIGN_RIGHT|wxBOTTOM|wxRIGHT, 10 );
	bSizer2->Add( bSizer10, 1, wxEXPAND, 5 );
	m_panel1->SetSizer( bSizer2 );
	m_panel1->Layout();
	bSizer1->Add( m_panel1, 1, wxEXPAND|wxALL, 5 );
	this->SetSizer( bSizer1 );
	this->Layout();
	this->Centre( wxBOTH );
	// Connect Events
	this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( MainFrameBase::OnCloseApp ) );
	m_button1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnClickCalcola ), NULL, this );
	}
	MainFrameBase::~MainFrameBase()
	{
	// Disconnect Events
	this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( MainFrameBase::OnCloseApp ) );
	m_button1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnClickCalcola ), NULL, this );
}


///////////////////////////////////////////////////////////////////////////
// Name: gui.h
// C++ code generated with wxFormBuilder (version Nov  5 2013)
// http://www.wxformbuilder.org/
// Author: Sala Carlo - 05/09/2024
///////////////////////////////////////////////////////////////////////////
#ifndef __GUI_H__
#define __GUI_H__
#include <wx/panel.h>
#include <wx/hyperlink.h>
#include <wx/button.h>
#include <wx/textctrl.h>
#include <wx/stattext.h>
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/menu.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/statusbr.h>
#include <wx/frame.h>
#include <wx/valtext.h>
#include <wx/listctrl.h>
///////////////////////////////////////////////////////////////////////////////
/// Class MainFrameBase
///////////////////////////////////////////////////////////////////////////////
class MainFrameBase : public wxFrame 
{
	private:
	protected:
		wxPanel* m_panel1;
		wxStaticText* m_staticText1;
		wxStaticText* m_staticText2;
		wxStaticText* m_staticText3;
		wxTextCtrl* m_textCtrl1;
		wxStaticText* m_staticText4;
		wxTextCtrl* m_textCtrl2;
		wxStaticText* m_staticText5;
		wxTextCtrl* m_textCtrl3;
		wxStaticText* m_staticText6;
		wxTextCtrl* m_textCtrl4;
		wxButton* m_button1;
		wxStaticText* m_staticText7;
		wxStaticText* m_staticText8;
		wxStaticText* m_staticText9;
		wxStaticText* m_staticText10;
		wxGenericHyperlinkCtrl* m_hyperlink1;
		wxStatusBar* m_statusBar;
		virtual void OnCloseApp( wxCloseEvent& event ) { event.Skip(); }
		virtual void OnClickCalcola( wxCommandEvent& event ) { event.Skip(); }
	public:
		MainFrameBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = "  Calcolo dell' area e del perimetro del rettangolo", const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCAPTION|wxCLOSE_BOX|wxMINIMIZE_BOX|wxSYSTEM_MENU|wxTAB_TRAVERSAL );
		~MainFrameBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class Rettangolo
///////////////////////////////////////////////////////////////////////////////	
	class Rettangolo
	{
	public:
	double b, h;
	double area()
	{
	return b*h;
	}
	double perimetro()
	{
	return 2*(b+h);
	}
};
#endif //__GUI_H__


/*********************************************************************
 * Name:      	main.cpp
 * Purpose:   	Implements simple wxWidgets application with GUI
 * 				created using wxFormBuilder.
 * Author:    	Sala Carlo
 * Created:   	05/09/2024
 *********************************************************************/
#include "main.h"
// initialize the application
IMPLEMENT_APP(MainApp);
////////////////////////////////////////////////////////////////////////////////
// application class implementation 
////////////////////////////////////////////////////////////////////////////////
bool MainApp::OnInit()
{
	SetTopWindow( new MainFrame( NULL ) );
	GetTopWindow()->Show();
	// true = enter the main loop
	return true;
}
////////////////////////////////////////////////////////////////////////////////
// main application frame implementation 
////////////////////////////////////////////////////////////////////////////////
MainFrame::MainFrame(wxWindow *parent) : MainFrameBase( parent )
{

}
MainFrame::~MainFrame()
{

}
void MainFrame::OnCloseApp( wxCloseEvent& event)
{
	Destroy();
}
void MainFrame::OnClickCalcola( wxCommandEvent& event)
{
	 char risultato[5] ="";
	 double base = 0;
     double altezza = 0;
	 m_staticText8->SetLabel("");
	 m_staticText10->SetLabel("");
	base = atof(m_textCtrl1->GetValue()+"."+ m_textCtrl2->GetValue());
	altezza = atof(m_textCtrl3->GetValue()+"."+ m_textCtrl4->GetValue());
    if(base == 0.00 || base <  0.00	|| altezza == 0.00 || altezza < 0.00) {
		wxMessageBox (_T("Valori non ammessi !!"),
		             _T("Avviso"), wxOK | wxICON_EXCLAMATION);
			base =0;
		    altezza = 0;		 
	} else {
		Rettangolo rett;
		rett.b = base;
		rett.h = altezza;
		sprintf(risultato ,"% 4.2f" , rett.area());
		m_staticText8->SetLabel(risultato);
		sprintf(risultato ,"% 4.2f" , rett.perimetro());
		m_staticText10->SetLabel(risultato);
	}
}


/*********************************************************************
 * Name:      	main.h
 * Purpose:   	Declares simple wxWidgets application with GUI
 * 				created using wxFormBuilder.
 * Author:    	Sala Carlo
 * Created:   	05/09/2024
 *********************************************************************/
#ifndef __main__
#define __main__
// main wxWidgets header file
#include <wx/wx.h>;
// gui classes generated by wxFormBuilder
#include "gui.h"
////////////////////////////////////////////////////////////////////////////////
// application class declaration 
////////////////////////////////////////////////////////////////////////////////
class MainApp : public wxApp
{
	public:
		virtual bool OnInit();
};
DECLARE_APP(MainApp)
////////////////////////////////////////////////////////////////////////////////
// main application frame declaration 
////////////////////////////////////////////////////////////////////////////////
class MainFrame : public MainFrameBase
{
	public:
		//MainFrameBase prova
		MainFrame( wxWindow *parent );
		virtual ~MainFrame();
	protected:
		// protected event handlers
		void OnCloseApp( wxCloseEvent& event );
		void OnClickCalcola( wxCommandEvent& event );
};
#endif //__main__

gif(Aggiornamento dell'articolo al 07/09/2025)

Terminale Facciamo un passo indietro.
Vi ho fatto vedere nell'esempio precedente come si possa eseguire con C++ e una libreria come wxWidgets, un programma ad interfaccia grafica a finestre.
Inizialmente però i sistemi operativi avevano solo una interfaccia testuale.
Prima di windows e di altri sistemi operativi con interfaccia grafica, si utilizzavano interfacce testuali come ad esempio il famoso "MSDOS".
Ora accanto all'interfaccia a finestre come nell'attuale windows 11, sopravvive ancora qualcosa che proviene dal passato come l'app "Terminale" o detta anche (windows 10) "PowerShell".
Io, avendo studiato all'università informatica negli anni 70 e poi con i personal computer negli anni 80 del secolo scorso, sono abbastanza capace di utilizzare anche tali interfacce.
Vi scrivo qui i codici sorgenti in C++ dello stesso programma Rettangolo visto in precedenza ma scritto utilizzando appunto questa intefaccia.
PROVATE VOI A COMPILARLO!
Le istruzioni più complete le potete trovare anche nell'ottimo manuale di Carlo Mazzone:
C e C++ Le chiavi della programmazione.

Non guardatemi male, anche la matematica e di conseguenza l'informatica sono al pari dell'arte e della poesia, una ricerca della perfezione. Purtroppo allo stato attuale delle cose sia l'arte che le scienze sono lontane dall'esserlo e spesso sono asservite al potere e alla pubblicità e se ne fanno cattivo uso anche da parte nostra.
Vedi: cattivo uso dell'"IA", di certo cinema, di certi spot, di certa politica e di certe altre discipline.

E ... prima del C++ e del C?
Prima c'era il linguaggio Assembler (Assemblatore). Tale linguaggio, assai primitivo, utilizzava del codice macchina in esadecimele (base 16). Questi linguaggi erano strettamente legati al microprocessore usato.
Ve lo risparmio ma sappiate però che ancora oggi, sotto sotto i più usati linguaggi c'è ancora l'assembler che è la base di programmazione di ogni cip.

Vi assicuro che tale procedura mi fece in un primo momento, odiare queste macchine con una violenza tale che, per molto tempo andai in crisi e non ripresi più a studiarle. -:)

Vi chiederete ora il perché utilizzo lo sfondo nero per il codice. Non è un colore politico ma lo sfondo nero garantisce che la maggior parte dei pixels siano spenti. E' RISPARMIO ENERGETICO :-)

png

Codici sorgentiScarica qui!


/*********************************************************************
 * Name:      	Rettangolo.cpp
 
 * Author:    	Sala Carlo
 * Created:   	05/09/2024
 *********************************************************************/
#include <iostream>
#include "Rettangolo.h"
using namespace std;
Rettangolo::Rettangolo(float a, float b)
{
	x= a;
	y= b;
}
Rettangolo::~Rettangolo()
{
	cout <<"Fine operazioni";
}
float Rettangolo :: Area()
{
	return x*y;
}
float Rettangolo :: Perimetro()
{
	return 2*x+2*y;
}

/*********************************************************************
 * Name:      	Rettangolo.h
 
 * Author:    	Sala Carlo
 * Created:   	05/09/2024
 *********************************************************************/
#ifndef RETTANGOLO_H_INCLUDED
#define RETTANGOLO_H_INCLUDED
class Rettangolo
{
public:
float x;
float y;
Rettangolo(float,float);
~Rettangolo();
float Area();
float Perimetro();
};
#endif //RETTANGOLO_H_INCLUDED

/*********************************************************************
 * Name:      	main.cpp
 * 
 * Author:    	Sala Carlo
 * Created:   	07/09/2025
 *********************************************************************/
#include <iostream>
#include "Rettangolo.h"
using namespace std;
int main()
{
char tasto;
system("COLOR 17");
do {
float F;
float G;
cout << "\nPerimetro e area di un rettangolo" << endl << endl ;
cout << "Inserisci la base" << endl;
cin >> F;
cout << "Inserisci la altezza" << endl;
cin >> G;
Rettangolo rettangolo1 (F,G);
cout << "Perimetro del rettangolo e': " << rettangolo1.Perimetro() << endl;
cout << "Area del rettangolo e': " << rettangolo1.Area() << endl;
cout <<  "\nPremi ESC per uscire o\n";
	cout <<  "un tasto qualsiasi per continuare ...\n";
	tasto=_getwch();
}
while (!((int)tasto== 27));
	return EXIT_SUCCESS;
}