PDA

View Full Version : [C++] GUI: esecuzione ciclo fino ad evento..


fdf86
30-07-2010, 13:46
Salve a tutti,
Avrei bisogno di una dritta.
Perdonate il titolo ma non mi veniva nulla di meglio:rolleyes:

Ho una GUI con vari bottoni..Lavora da server e da client contemporaneamente con un applicazione esterna che effettua dei calcoli e restituisce i risultati.
Tramite la GUI invio dei comandi su una porta e ricevo risposte e risultati su altre due porte differenti (questo è imposto dall'applicazione esterna).
Ho un pulsante che avvia il calcolo ed uno che lo ferma.
Vorrei acquisire e mandare a video (magari plottare in un grafico, ma questo lo vediamo dopo semmai) i risultati dopo l'avvio della simulazione finchè non viene premuto il tasto che stoppa il tutto..Come fare?
Credevo bastasse un while che controllasse una variabile globale o direttamente un evento ma non funziona..Una volta entrato nel while non riesco a cliccare altri pulsanti e quindi ad aggiornare la condizione del while.
Spero di non essere stato troppo confusionario.
Attendo suggerimenti, grazie

Francesco

banryu79
30-07-2010, 14:10
Credevo bastasse un while che controllasse una variabile globale o direttamente un evento ma non funziona..Una volta entrato nel while non riesco a cliccare altri pulsanti e quindi ad aggiornare la condizione del while.

Così a naso direi che in questo modo il tuo ciclo viene eseguito dal thread dell'event-loop della GUI, quindi lo stai "congelando".
Dovresti delegare ad un altro thread questo lavoro.

Potresti dirci almeno in che linguaggio stai sviluppando, su quale sistema e con che libreria grafica per la GUI?
(Per quanto riguarda il titolo avresti dovuto prima leggere il regolamento, avrei evitato la domanda qui sopra)

fdf86
30-07-2010, 14:26
Hai ragione,scusa..stavo giusto dandomi dell'imbecille perchè non avevo scritto cosa uso..poi ho visto che avevi già risposto..
Sto Usando WxDevC++ (uso la WxWidget) su wundows 7...ed uso la winsock.h (ma questo non credo serva).
Si credo che il problema sia proprio quello quindi devo delegare un altro button?

del tipo:

http://www.functionx.com/vccli/general/events.htm

Almeno il concetto insomma..

Scusami ma non sono espertissimo..Per la tesi ( ing Meccanica ) mi serve l'altro programma (OpenModelica per la cronaca) che è in continuo sviluppo..e quindi sono un mese che lavoro su cose mai viste prima..server, interfacce tra linguaggi, ed ora GUI..mi perdonerai spero.

Grazie ancora,
Francesco

Teo@Unix
30-07-2010, 22:09
Scusami ma non sono espertissimo..Per la tesi ( ing Meccanica ) mi serve l'altro programma (OpenModelica per la cronaca) che è in continuo sviluppo..e quindi sono un mese che lavoro su cose mai viste prima..server, interfacce tra linguaggi, ed ora GUI..mi perdonerai spero.


ti capisco, tanto di cappello perchè splittare da un cosa all'altra all'inizio non è semplice. Io idem da quando lavoro.... però si impara parecchio così. :)
Comunque non ho capito bene chi effettua i calcoli... il server? Oppure il tuo client? Semmai prova a fare uno schema.
Se è il client che fa i calcoli, se non ho capito male vuoi un modo per fermare la computazione però hai il problema che la GUI a quel punto non risponde perchè è impegnata nel calcolo. Se è così devi per forza usare un thread separato.

fdf86
31-07-2010, 00:06
Grazie..me ne sono accorto..purtroppo all'università (almeno alla mia) si fanno molte cose ma tutte en passant..io approfondisco in genere, per quel che si può approfondire col vecchio/nuovo ordinamento trimestrale..ma poi quando metto da parte un programma per un po' devo ricominciare tutto da capo...
Comunque..Allora lo schema è questo:



Applicazione______________Porte______________GUI


10501
Control Server <------------------------------ Client
comando



10500
Control Client ------------------------------> Server
risposta


10502
Transfer Client ------------------------------> Server
risultati




L'applicazione esterna (OMI ,OpenModelica-Interactive )fa i calcoli..è stata implementata da gente molto esperta (credo e spero :p ) e quindi è fatta apposta per calcolare, ricevere input e trasmettere output contemporaneamente..
La mia interfaccia serve per settare dei parametri, inviare i comandi di avvio pausa e fine, e visualizzare i risultati..
Le cose funzionano bene..i risultati li scrivo comunque in un file esterno..non vanno persi..Vorrei però visualizzarli mentre eseguo visto che OMI li trasmette..
diciamo che mi servirebbe questo ciclo while da quando clicco start a quando clicco pause o stop..
Appena posto provo a metterci qualcosa del genere..

http://wxforum.shadonet.com/viewtopic.php?t=862&highlight=delegate
e vi faccio sapere.

Grazie mille

Francesco

fdf86
31-07-2010, 21:19
Ciao a tutti di nuovo..
Dopo una mezza giornata di studio e lavoro sono riuscito a creare quel thread..
Pare funzioni..solo che non riesco a chiamare la Delete() (o la Pause() )da un button diverso da quello dove lo inizializzo:

In GUIsFrm.cpp


void GUIsFrm::WxButton2Click(wxCommandEvent& event)
{
............
//creo il thread in WxButton2Click

MyThread *PlotResult = new MyThread(WxMemo2,remoteSocket_res);

PlotResult->Run();
.......
...
//e lo chiudo in WxButton3Click


void GUIsFrm::WxButton3Click(wxCommandEvent& event)
{

PlotResult->Delete();

.........
.........

MyThread::MyThread(wxTextCtrl* WxMemo2, SOCKET remoteSocket_res)
:wxThread(),WxMemo2(WxMemo2),remoteSocket_res(remoteSocket_res)
{
Create();
}


void* MyThread::Entry()
{

char buf[500];
int n;
while(1)
{
n=recv(remoteSocket_res, buf, sizeof(buf), 0);
buf[n]=0;
(*WxMemo2)<<buf<<"\n";

if(TestDestroy())
break;
}
return 0;
}





Vi posto anche altre parti del progetto che non so se siano totalmente corrette e soprattutto ben collocate.(il Progetto si chiama GUIs)

In GUIsFrm.h





#include "MyThread.h"

////Dialog Style Start
#undef GUIsFrm_STYLE
#define GUIsFrm_STYLE wxCAPTION | wxSYSTEM_MENU | wxMINIMIZE_BOX | wxCLOSE_BOX
////Dialog Style End



class GUIsFrm : public wxFrame
{
private:
DECLARE_EVENT_TABLE();

public:
GUIsFrm(wxWindow *parent, wxWindowID id = 1, const wxString &title = wxT("GUIs"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = GUIsFrm_STYLE);
virtual ~GUIsFrm();

void WxButton1Click(wxCommandEvent& event);
void WxButton2Click(wxCommandEvent& event);
void WxButton3Click(wxCommandEvent& event);
void WxButton4Click(wxCommandEvent& event);
void GUIsFrmActivate(wxActivateEvent& event);
void WxButton5Click(wxCommandEvent& event);
void WxSlider1Scroll(wxScrollEvent& event);
void WxSlider2Scroll(wxScrollEvent& event);
void crea_addr(struct sockaddr_in* ,int , char* );
MyThread *PlotResult;

................



In MyThread.h

#ifndef __MYTHREAD_H
#define __MYTHREAD_H


#include <wx/thread.h>

class MyThread : public wxThread
{
wxTextCtrl *WxMemo2;
bool sim;
SOCKET listenSocket_res;
SOCKET remoteSocket_res;


public:
MyThread(wxTextCtrl *WxMemo2, SOCKET remoteSocket_res);
virtual ExitCode Entry();
};

#endif



La GUI smette di funzionare quando clicco su un bottone che contiene la Delete(). Non succede se la inserisco nello stesso pulsante in cui lo creo.

Inoltre ho notato che se non inserisco la Delete() funziona abbastanza bene..cioè smette di scrivere risultati (anche perchè il simulatore non ne manda)..Solo non riesco a leggere più nulla se riavvio la simulazione.
devo inizializzare il Thread da qualche altra parte? Eventualmente, È proprio necessaria questa Delete?


Grazie in anticipo ;)
Francesco