How can i display numbers in wxWidgets? Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
artorias807
In need of some credit
In need of some credit
Posts: 5
Joined: Wed May 06, 2020 6:47 am

How can i display numbers in wxWidgets?

Post by artorias807 » Wed May 06, 2020 7:01 am

My idea is to make a stopwatch app. I have 2 buttons Start and Pause and a Listbox. When i press start the timer starts running and when i press pause the timer should stop and calculate the elapsed time and add that to the listbox. My timer is made out of 3 int valuse hour minute and second and i increment the second and when it reaches 60 minute turns to 1 sec turns to 0 basic stuff but works fine but i want to display these int variables.
My problem is that i have no idea how to display the timer in my wxFrame. Is there like a class similar to wxTextCtrl but with numbers? Also i want to be able to adjust the size of the numbers since i want them to be placed in the middle (of whatever it holds/displays it). As the attached picture shows i tried to make the numbers into a wxString but clearly that didn't work not to mention that as i said i don't want the timer to be this small and wrongly placed. Any ideas? :?:
Attachments
workapp.PNG
workapp.PNG (4.23 KiB) Viewed 150 times

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2387
Joined: Sun Jan 03, 2010 5:45 pm

Re: How can i display numbers in wxWidgets?

Post by PB » Wed May 06, 2020 9:09 am

The simplest would probably be to use a wxStaticText, e.g.:.
stopwatch.png
stopwatch.png (2.76 KiB) Viewed 138 times

Code: Select all

#include <wx/wx.h>
#include <wx/datetime.h>

class MyDialog : public wxDialog
{
public:
    MyDialog() : wxDialog(nullptr, wxID_ANY, "Test")
    {
        wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
        wxButton* button = nullptr;
        wxFont font;

        m_timeDisplay = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 
            wxALIGN_CENTRE_HORIZONTAL | wxST_NO_AUTORESIZE | wxBORDER_SIMPLE );
        font = m_timeDisplay->GetFont();
        font.MakeBold().MakeLarger();
        m_timeDisplay->SetFont(font);
        UpdateDisplayedTime();
        mainSizer->Add(m_timeDisplay, wxSizerFlags().Expand().DoubleBorder());

        button = new wxButton(this, wxID_ANY, "Start timer");
        button->Bind(wxEVT_BUTTON, &MyDialog::OnStartTimer, this);
        mainSizer->Add(button, wxSizerFlags().Expand().Border());

        button = new wxButton(this, wxID_ANY, "Stop timer");
        button->Bind(wxEVT_BUTTON, &MyDialog::OnStopTimer, this);
        mainSizer->Add(button, wxSizerFlags().Expand().Border());

        m_timer.Bind(wxEVT_TIMER, &MyDialog::OnUpdateDisplayedTime, this);

        SetSizerAndFit(mainSizer);
    }
private:
    wxStaticText*  m_timeDisplay;
    wxTimer m_timer;
    wxDateTime m_startTime;

    void OnStartTimer(wxCommandEvent&)
    {
        m_startTime = wxDateTime::Now();
        m_timer.Start(1000); // every second
        UpdateDisplayedTime(); // update immediatelly do not wait a second
    }

    void OnStopTimer(wxCommandEvent&)
    {
        m_timer.Stop();
        UpdateDisplayedTime();
    }

    void OnUpdateDisplayedTime(wxTimerEvent&)
    {
        UpdateDisplayedTime();
    }

    void UpdateDisplayedTime()
    {
        if ( m_timer.IsRunning() )
        {
            const wxDateTime currentTime = wxDateTime::Now();
            const wxTimeSpan ellapsedTime = currentTime - m_startTime;
        
            m_timeDisplay->SetLabel(ellapsedTime.Format("%D:%H:%M:%S"));
        }
        else
        {
            m_timeDisplay->SetLabel("  <Not Timing>  ");
        }
    }
};

class MyApp : public wxApp
{
public:
    bool OnInit() override
    {
        MyDialog().ShowModal();
        return false;
    }
}; wxIMPLEMENT_APP(MyApp);

artorias807
In need of some credit
In need of some credit
Posts: 5
Joined: Wed May 06, 2020 6:47 am

Re: How can i display numbers in wxWidgets?

Post by artorias807 » Wed May 06, 2020 10:56 am

Hey!
Your answer was VERY helpful and also you showed me that i do not need to implement my own timer wich is way easier. My code looks different when it comes to the grider but the code is jsut not working.. :oops:
My code(cMain.cpp):

Code: Select all

cMain::cMain() : wxFrame(nullptr, wxID_ANY, "WorkApp", wxDefaultPosition, wxSize(600, 450))
{
	wxGridSizer* grid = new wxGridSizer(4, 0, 1, 1);

	button = new wxButton(this, 101, "Start", wxPoint(10, 10), wxSize(150, 50));
	button->Bind(wxEVT_BUTTON, &cMain::OnStartButtonClicked, this);
	grid->Add(button, 1, wxEXPAND | wxALL);


	button = new wxButton(this, 102, "Stop", wxPoint(0, 0), wxSize(150, 50));
	button->Bind(wxEVT_BUTTON, &cMain::OnStopButtonClicked, this);
	grid->Add(button, 1, wxEXPAND | wxALL);

	timerDisplay = new wxStaticText(this, 103, "", wxPoint(10, 300), wxSize(150, 50), wxALIGN_CENTRE_HORIZONTAL | wxST_NO_AUTORESIZE | wxBORDER_SIMPLE);
	font = timerDisplay->GetFont();
	font.MakeBold().MakeLarger();
	timerDisplay->SetFont(font);
	UpdateDisplayedTime();
	grid->Add(timerDisplay, 1, wxEXPAND | wxALL);

	this->SetSizer(grid);
	grid->Layout();
}

cMain::~cMain()
{

}

void cMain::UpdateDisplayedTime()
{
	if (timer.IsRunning()) {
		const wxDateTime currentTime = wxDateTime::Now();
		const wxTimeSpan ellapsedTime = currentTime - startTime;

		timerDisplay->SetLabel(ellapsedTime.Format("%H:%M:%S"));
	} else {
		timerDisplay->SetLabel("  <Not Timing>  ");
	}
}

void cMain::OnUpdateDisplayedTime(wxTimerEvent& evt)
{
	UpdateDisplayedTime();
}


void cMain::OnStartButtonClicked(wxCommandEvent& evt)
{
	startTime = wxDateTime::Now();
	timer.Start(1000); // every second
	UpdateDisplayedTime(); // update immediatelly do not wait a second
}

void cMain::OnStopButtonClicked(wxCommandEvent& evt)
{
	timer.Stop();
	UpdateDisplayedTime();
}

Kvaz1r
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 207
Joined: Tue Jun 07, 2016 1:07 pm

Re: How can i display numbers in wxWidgets?

Post by Kvaz1r » Wed May 06, 2020 12:21 pm

It would be much better if you provide full reproducible sample.
But I already see how you 2 times assign value to one member:
here:

Code: Select all

button = new wxButton(this, 101, "Start", wxPoint(10, 10), wxSize(150, 50));
and here:

Code: Select all

button = new wxButton(this, 102, "Stop", wxPoint(0, 0), wxSize(150, 50));
Two buttons therefore should be two variables and not one.

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2387
Joined: Sun Jan 03, 2010 5:45 pm

Re: How can i display numbers in wxWidgets?

Post by PB » Wed May 06, 2020 12:26 pm

I do not think that reusing button variable matters here.

But I do not see the timer event being Bind()ed anywhere, i.e., something like

Code: Select all

timer.Bind(wxEVT_TIMER, &cMain::OnUpdateDisplayedTime, this);

artorias807
In need of some credit
In need of some credit
Posts: 5
Joined: Wed May 06, 2020 6:47 am

Re: How can i display numbers in wxWidgets?

Post by artorias807 » Wed May 06, 2020 1:38 pm

You are absolutely right!
I was so happy that i can customize the timer i forgot to Bind it!
Thank you very much!

Post Reply