TImages flackern im TPanel



  • Hi,

    ich habe ein TPanel(welches Transparent ist, sodass man das Hintergrundsbild durch sieht) erstellt in dem ich mehrere TImages drinnen habe. Das Panel soll einen Button darstellen und die Verschiedenen Bilder sollen für ein- und ausgeblendet werde, je nachdem ob die Maus über das Panel fährt oder die Maus gedrückt wird.

    Das funktioniert auch alles, nur ist das Problem das jedes Mal Wenn ein TImage auf sichtbar gewechselt wird für eine ganz kurze Zeit die Transparenten stellen Weiß erscheinen und dadurch sieht das Ganze nicht mehr besonders schön aus.
    (Mache ich die Transparenz des TPanels weg habe ich zwar kein flackern, aber da mein Butten nicht Rechteckig ist einen unerwünschten Rahmen von dem Panel um meinen Button

    Habe versucht das Problem mit DoubleBuffered zu lösen, hat jedoch keine Änderung bewirkt.

    Gruß
    Jarhead



  • hat hier keine schonmal mit diesem Problem zu tun gehabt?



  • Wenn du den verantwortlichen Codeausschnitt postest, kann ich mich dem Problem gerne mal annehmen.



  • Ich habe im c++ Builder folgendes gemacht:

    In einer Form habe ich als ersten ein TImage als Hintergrundsbild erstellt.
    Dann habe ich die mitte der Form ein TPanel plaziert.
    Das TPanel ist so eingestellt das es Transparent ist und keinen Rand hat.
    (folglich sieht man das Hintergrundbild einfach durch und das Panel ist unsichtbar)
    In dem TPanel sind 2 TImages welche direkt übereinander liegen. (eines davon ist Visible = false)
    Nun habe ein Ereigniss erstellt welches durch das Bewegen der Maus über das sichtbare Bild das andere auf Visible = true setzt. Beim Bewegen der Maus über das Panel oder das Hintergrundbild wird Visible wieder auf false gesetzt.

    void __fastcall Form1::Image2MouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
    {
        Image1->Visible = true;
    }
    
    void __fastcall Form1::I_BackgroundMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
    {
        Image1->Visible = false;
    }
    

    Kannst du damit was anfangen und eventuell den fehler finden?
    bin jetzt das wochenende nicht da, komm sontag wieder. wäre cool wenn hier dann die lösung stände.



  • Hallo
    Hast Du

    Panel1->DoubleBuffered=true;
    

    mal probiert?

    wNw



  • Hallo,

    erstelle zwei Bitmap, in die du deine Grafiken lädst.
    Dann ist ein TImage ausreichend, welches je nach Ereignis das betreffende Bitmap zugewiesen bekommt:

    //*.h
    private:
    	Graphics::TBitmap* bmp1;
    	Graphics::TBitmap* bmp2;
    
    //*.cpp:
    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner)
    {
       bmp1 = new Graphics::TBitmap;
       bmp1->LoadFromFile("bild1.bmp");
    
       bmp2 = new Graphics::TBitmap;
       bmp2->LoadFromFile("bild2.bmp");
    
       FGImage->Transparent = true;
    }
    __fastcall TForm1::~TForm1(void)
    {
       delete bmp1;
       delete bmp2;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Panel1MouseMove(TObject *Sender, TShiftState Shift, int X,
    		  int Y)
    {
       FGImage->Picture->Graphic = bmp2;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FGImageMouseMove(TObject *Sender, TShiftState Shift, int X,
    		  int Y)
    {
       FGImage->Picture->Graphic = bmp1;
    }
    

    mfg
    kpeter



  • Danke schonmal, das war echt eine schöne idee, flackert bei mir aber leider genau so.

    hätte jemand vieleicht noch einen anderen lösungsvorschlag.



  • Das Flackern entsteht innerhalb des jeweiligen MouseMove-Event durch unnötiges Nachladen, derweil sich der Maus-Cursor noch über der Komponente befindet.
    Abhilfe erreicht man durch Setzen von Boolschen Werten

    :
      bool bPanel = true; // Maus über TPanel
      bool bImage = false; // Maus über TImage
    

    Die Ereignisse aus meinem obigen Beispiel sähen dann so aus:

    void __fastcall TForm1::Panel1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
    {
       if (bImage) {
          bPanel = true;
          bImage = false;
          FGImage->Picture->Graphic = bmp2;
       }
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FGImageMouseMove(TObject *Sender, TShiftState Shift, int X,
    		  int Y)
    {
       if (bPanel) {
          bPanel = false;
          bImage = true;
          FGImage->Picture->Graphic = bmp1;
       }
    }
    //---------------------------------------------------------------------------
    

    Gleich im Konstruktor muss man einen Wert auf true setzen (zB bPanel = true;)

    mfg
    kpeter



  • Da hast du recht, dadurch kommt auch ein flackern zu stande, aber das habe ich meinem Aktuellen code schon beachtet, denoch ist bei jedem welchseln des Bildes das Flakern da.

    Mache ich es ohne Transparentes Panel ist auch gakrin flakern zu sehen. Nur wenn ich das Panel Transparent habe, sodass der Hintergrund duch scheint kommt es zum flackern, aber diese Transparenz des Panels würde ich halt gerne nützen



  • Kann ich vieleicht irgendwo ein kleines Beispielprogramm hoch laden. Dann könntet ihr euch das Problem live anschauen.



  • jarhead_02 schrieb:

    Kann ich vieleicht irgendwo ein kleines Beispielprogramm hoch laden.

    Klar. Ich empfehle Dropbox. Ein Beispielprojekt reduziert zumindest die Hemmschwelle, sich mit deinem Problem zu beschäftigen, schonmal deutlich 😉



  • Hallo

    Du kannst dein Beispielprojekt (Builder-Projekt inklusive Quellcode, nicht fertig kompiliert) auf einen dir bekannten Freehoster wie Rapidshare hochladen und dann den Link hier posten.

    bis bald
    akari



  • akari schrieb:

    Rapidshare

    (Etwas off-topic, aber ich verstehe nicht, warum so viele Leute RapidShare benutzen/empfehlen. Diese Wartezeiten-Gängelung ist doch eine Zumutung.)



  • Hab es jetzt auf Rapidshare hochgeladen.
    Dopbox schien mir mehr für Private zweche zu sein.

    https://rapidshare.com/files/2555376495/GridPanel.rar



  • jarhead_02 schrieb:

    Dopbox schien mir mehr für Private zweche zu sein.

    Taugt auch dafür prima. Du hast einen "public folder" auf deiner Festplatte, in den du irgendwas reinkopieren kannst, dann im Explorer Rechtsklick->Dropbox->URL kopieren, die URL hier posten, fertig.

    Dropbox ist für Privates genaugenommen viel weniger geeignet als für sowas. Bevor man dort persönliche Daten hochlädt, sollte man sich ein paar Gedanken über die Verschlüsselung machen...



  • Und hat schonmal jemand das Bsp. Projekt angeschaut? Irgendwelche einfälle?

    Ja die Dropbox klingt auch ganz gut, aber bei Rapidshare habe ich etwas mehr das gefühl anonym zu bleiben.



  • Bei jeder Mausbewegung im Image das Bild neu zu laden ist wohl ein bisschen over...

    Keine Ahnung was du jetzt genau vor hast, aber würde es nicht reichen dein Bild mit OnMouseEnter und mit OnMouseLeave einmalig zu verändern dann brauchste auch nicht diese test bool variable?

    Bzw. kannst du ja auch noch im Konstruktor deine Bilder "Vorladen" und diese dann dem TImage zuweisen (würde auch ein wenige Zeit einsparen).

    Desweiteren FESTE Pfade ala
    E:/Grafische Objekte/Button/Blau/Final/Home/Key_Blanc_Normal_Smal.png
    im Programm zu verwenden ist sehr schlecht, weil ich habe gar kein E und schon gar nicht die Grafiken in dieser Verzeichnisstruktur.
    Also arbeite z.B. mit
    ExtractFilePath(Application->ExeName)+"Image/Key_Blanc_Normal_Smal.png";
    und evtl. vorher überprüfen mit FileExists ob diese Datei auch existiert.



  • Dir schonmal vielen Dank das du dich mit meinem Problem beschäftigst. Ist gerade mein Hauptpoblem damit ich endlich mit meinem Projekt vorfahren kann.

    Die änderung auf OnMouseEnter und OnMouseLeave macht definitiv sinn. Habe ich gemacht.

    Das mit dem "Vorladen" und dem TImage zuweisen habe ich ausprobiert. Das sieht bei mir jetzt so aus.

    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner)
    {
    	Image6->Picture->LoadFromFile("Key_Blanc_Normal_Smal.png");
    	Image5->Picture->LoadFromFile("Key_Normal_Small.png");
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Image1MouseEnter(TObject *Sender)
    {
    	Image1->Picture = Image5->Picture;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Image1MouseLeave(TObject *Sender)
    {
    	Image1->Picture = Image6->Picture;
    }
    

    War das von dir so gemeint? Muss ich da dann für jedes Bild einer TImage eine Zusätzliche unsichtrbaere TImage erstellen? oder gibt es da wieder eine bessere Lösung.

    Leider hatte aber auch diese änderung nicht bewirkt das das Flakern verschwindet.
    Hättest daher vieleicht noch ne weitere Idee? oder habe ich da irgendwas falsch gemacht?

    Ja das mit den Festen Pfaden hatte ich nur bei mir gemacht, da ich noch am rumprobieren war und nicht immer die Images in die einzelnen ordner des jeweiligen Projekts kopieren wollte. Hatte dies aber eigendlich noch gemacht, bevor ich es auf RapidShare hochgeladen habe. Vieleicht hatte ich vergessen das Projekt davor noch abzuspeichern.

    Zu:
    ExtractFilePath(Application->ExeName)+"Image/Key_Blanc_Normal_Smal.png";
    was genau macht das? (Soll das vieleicht ein Beispiel sein wie ich das Bild "Vorlade", Wenn ja: wie kann ich das genau nutzen?)



  • ExtractFilePath(Application->ExeName)
    macht nichts anderes als dir den Pfad zu deiner EXE-Datei zurückzugeben
    und in diesem Pfad kannst du dann zB deine Bilder speichern.

    Willst du Überhaupt das deine Bilder von "außen" veränderbar sind,
    da du diese ja nicht mit in die EXE einkompilierst?

    Bei mir flackert eigentlich nichts mehr nach dem umstellen auf OnMouseLeave/OnMouseEnter.



  • ExtractFilePath(Application->ExeName) scheint dann ja doch an manchen Stellen sehr hilfreich zu sein.

    Ich habe vor, die Bilder nur von "außen" zu laden, sodass ich verschiedenen Designs laden kann.
    (Hab da aber noch das Problem das die Bilder welche ich im C++ Builder verwende ja dennoch in die .exe mit einkompiliert werden. Wenn du wüstest wie ich dies recht leicht umgehen kann würde mich das auch sehr freuen.)

    Also ich habe mein Programm jetzt mal an nem anderen Rechner laufen lassen, dort muss ich sagen flackert es nicht bei jedem Wechsel des Bildes, aber es ist immer noch nicht ganz weg.

    Da dieses flackern irgendwie nicht weg gehen möchte frage ich dich, ob die Button den auf andere Weise erstellt hättest. (Sie sollen halt aufleuchten wenn man mit der Maus rüber geht und versenken wenn Man die Maus drückt. Ich habe das halt durch wechseln der TImages realisiert. Hast du da vieleicht eine Besser und Standartmäßigere Lösung?)

    Kann dies eventuell an meiner Version vom C++ Builder liegen?
    Ich habe: Embarcadero RAD Studio 2010


Anmelden zum Antworten