[wxWidgets]Wyświetlanie zewnętrznych obrazków

Odpowiedz Nowy wątek
2006-11-19 19:44
Omar
0

Jak wyświetlić obrazek tak, aby nie był on kompilowany. To znaczy, że program wyświetla obrazek hello.bmp. I bez ingerowania w kod programu mogę zmienić wyświetlany obrazek.

Pozostało 580 znaków

2006-11-19 23:28
0

Daj na formatkę OpenFileDialog, ustaw Extensions na *.bmp. Dołóz jeszcze StaticBitmap z zakładki Controls i ustaw jakiś rozmiar. Do tego daj buttona i w funkcji obsługi wpisz taki kod:

void listboxFrm::WxButton2Click(wxCommandEvent& event)
{
    // insert your code here
    wxString nazwa="";
    WxOpenFileDialog1->SetDirectory(wxGetCwd());
    if(WxOpenFileDialog1->ShowModal()==wxID_OK)
    nazwa=WxOpenFileDialog1->GetPath(); 
    if(nazwa.Len()>0){
  wxBitmap*b=new wxBitmap(nazwa, wxBITMAP_TYPE_BMP);
  if(b){
   WxStaticBitmap2->SetBitmap(*b);   
        }  
}
}

Powinno pokazać plik bmp. A szczegóły można dopracować.

Pozostało 580 znaków

2006-11-21 20:53
Omar
0

A jak to zrobić bez OpeFileDialog? To znaczy, że otwiera tylko plik hello.bmp ?
I czy z innymi formatami też tak można?

Pozostało 580 znaków

2006-11-21 20:59
0
chodnik napisał(a)
void listboxFrm::WxButton2Click(wxCommandEvent& event)
{
wxBitmap*b=new wxBitmap(nazwa, wxBITMAP_TYPE_BMP);
if(b) //<---- hmm, new wyrzuca wyjątek
{
WxStaticBitmap2->SetBitmap(*b);   
}  
}
}

Oj chyba cieknie ;)

Pozostało 580 znaków

2006-11-21 21:43
0

Oj chyba cieknie

Możesz przybliżyć o co chodzi? Znaczy, że new nie zwróci null? Gdzieś mi się obiło o oczy, że operator new jest inaczej zdefiniowany, ale się temu nie przyglądałem za bardzo.

A jak to zrobić bez OpeFileDialog?

void listboxFrm::WxButton2Click(wxCommandEvent& event)
{
        // insert your code here

  wxBitmap*b=new wxBitmap("hello.bmp", wxBITMAP_TYPE_BMP);
  if(b){
   WxStaticBitmap2->SetBitmap(*b);   
        } 

}

Z innymi formatami plików jest troszkę inaczej... Poszukaj w dokumentacji klasy wxBitmap. Zobacz też wxImage.

Pozostało 580 znaków

2006-11-21 22:36
0
chodnik napisał(a)

Możesz przybliżyć o co chodzi? Znaczy, że new nie zwróci null? Gdzieś mi się obiło o oczy, że operator new jest inaczej zdefiniowany, ale się temu nie przyglądałem za bardzo.

Przyjęte jest, że operator new wyrzuca wyjątek - std::bad_alloc. Oczywiście w starszych kompilatorach może być inaczej ;) Ale nie o to mi głównie chodzi. wxStaticBitmap::SetBitmap robi "kopie" bitmapy więc alokacja jest niepotrzebna (i co gorsza, nie zwalniasz jej).

Tak powinno działać:

void listboxFrm::WxButton2Click(wxCommandEvent& event)
{
    WxStaticBitmap2->SetBitmap(wxBitmap(nazwa, wxBITMAP_TYPE_BMP));
}

Pozostało 580 znaków

2006-11-21 23:02
0

virtual void SetBitmap(const wxBitmap& label)
Taka jest definicja tej funkcji. Ja tam widzę referencję do bitmapy, dlatego mój kod był tak napisany. Gdzie się mylę?

Pozostało 580 znaków

2006-11-21 23:48
0

No przecież napisałem, że nie zwalniasz obiektu wxBitmap. A to, że jest tam referencja nie oznacza, że musisz ten obiekt tworzyć na stercie ;)

Pozostało 580 znaków

2006-11-22 11:55
0

Rzeczywiście działa to tak, jak napisałeś. Bitmapa jest tworzona na stosie, po zakończeniu funkcji WxBuuton2Click jest usuwana (nadpisywana) ze stosu, ale program działa. Wynika z tego, że rzeczywiście jest robiona kopia. Tylko w takim razie po co jest tam to przyjęcie bitmapy przez referencję? Właśnie to zasugerowało mi, że obiekt musi istnieć, bo SetBitmap musi móc się do niego zawsze odwoływać (np. przy odrysowaniu okna). Ale jak sprawdziłem, wcale nie musi.

Pozostało 580 znaków

2006-11-22 15:10
0
chodnik napisał(a)

Wynika z tego, że rzeczywiście jest robiona kopia.

Tyle, że:

This operator (=) does not copy any data, but instead passes a pointer to the data in bitmap and increments a reference counter. It is a fast operation

Tylko w takim razie po co jest tam to przyjęcie bitmapy przez referencję?

Poczytaj czym różni się przekazywanie obiektów "przez wartość" i "przez referencje".

Właśnie to zasugerowało mi, że obiekt musi istnieć, bo SetBitmap musi móc się do niego zawsze odwoływać

Jeżeli by tak było to miałbyś odpowiednią notkę w dokumentacji. Przykład:

wxMenuBar::Append(wxMenu *menu, const wxString& title)

menu
The menu to add. Do not deallocate this menu after calling Append.

title
The title of the menu.

podobnie z

wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)

menu
The menu to add. wxMenuBar owns the menu and will free it.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0