Komisches Aussehen unter Windows

Plattformunabhängige GUIs mit wxWidgets.
basti33
User
Beiträge: 56
Registriert: Donnerstag 24. August 2006, 15:05

Hallo,

ich habe mir ein kleines Programm mit wxPython geschrieben, das auch so läuft wie soll. Das einzige Problem ist, dass es unter Windows einfach scheiße aussieht.
http://img151.imageshack.us/my.php?imag ... hotms1.jpg Mich stören die dunkelgrauen Teile des Fensters. Ich dachte immer, das tolle an wxPython wäre der native Look&Feel. Was mache ich falsch? Unter Linux habe ich native Look&Feel.

Danke
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Das ist der native Look (so wie du ihn eingestellt hast (oder per default) unter "Darstellung"). Jedes Element hat eine definierte Farbe. Kuck mal unter Eigenschaften Darstellung.

Rechtsklick auf den Desktop->Eigenschaften->Darstellung->Erweitert.

Dort ist die Farbe vergeben wie bestimmte Elemente aussehen sollen. Z.B. Der Rand eines inaktieven Fensters oder die Hintergrundfarbe eines Dialogs, usw.

lg

EDIT: Korrektur.
Zuletzt geändert von sape am Freitag 22. Dezember 2006, 13:55, insgesamt 1-mal geändert.
basti33
User
Beiträge: 56
Registriert: Donnerstag 24. August 2006, 15:05

Danke.

Was muss ich in meinem Programm angeben, dass der Fensterhintergrund genauso grau wird, wie beispielsweise die Menüleiste?

Danke
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Also du möchtest die Farbe im Programm direkt fest einstellen? Von welchen wxWidget hast du abgeleitet? wxFrame?

€: Moment ich kuck mal eben in der doku...
Zuletzt geändert von sape am Freitag 22. Dezember 2006, 14:00, insgesamt 1-mal geändert.
basti33
User
Beiträge: 56
Registriert: Donnerstag 24. August 2006, 15:05

sape hat geschrieben:wxFrame?
Ja
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Ich schau mal eben in der doku
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

http://wxwidgets.org/manuals/2.6.3/wx_w ... oundcolour

Z.B.:

Code: Alles auswählen

self.SetBackgroundColour((0, 0, 0))
Das wir im Konstruktor gemacht. Ob es außerhalb vom Konstruktor geht habe ich noch nicht getestet. Es wird also ein Tumple übergeben, das die Werte als RGB angegeben hat (Z.B. (0, 0, 0,) für Schwarz)

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
import wx
        
class MainFrame(wx.Frame):
    def __init__(self, parent=None, id=-1, title = "MyApp"):
         wx.Frame.__init__(self, parent, id, title)
         
         self.SetBackgroundColour((0, 0, 0))
         
                  
def main():
    app = wx.PySimpleApp()
    mf =  MainFrame()
    mf.Show()
    app.MainLoop()

if __name__ == "__main__":
    main()
lg
Zuletzt geändert von sape am Freitag 22. Dezember 2006, 14:12, insgesamt 1-mal geändert.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Die Methode haben alle xwWidgets die von `wxWindow` abgeleitet sind. Also alle GUI-Spezifischen wxWidgets.
basti33
User
Beiträge: 56
Registriert: Donnerstag 24. August 2006, 15:05

Danke.

Aber ein paar Fragen habe ich noch.
1. Muss ich jetzt nachschauen, welches Grau dem Windowsgrau am ähnlichsten ist, und das dann einsetzen?
2. Wie wird das in anderen Programmen gemacht? Ich habe noch nie ein Programm gesehen, das einen solchen Hintergrund hat.

Danke
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Nein, in der Regel reicht es einfach ein wx.Panel in den wx.Frame zu knallen und dort dann die Widgets anzuordnen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

basti33 hat geschrieben: 1. Muss ich jetzt nachschauen, welches Grau dem Windowsgrau am ähnlichsten ist, und das dann einsetzen?
Ja. Du installierst dir ein Programm wie Gimp und suchst dir den Farbton aus den du haben möchtest. Es wird dir bei der Farbauswahl immer die RGB Werte angezeigt. Diese Trägst du dann ein.

Ich persönlich würde aber keine Feste Vorgabe von Farbwerten in der Applikation einprogrammieren, sondern es dem OS überlassen. Das sorgt für ein einhaltliches Design aller Applikationen.
basti33 hat geschrieben: 2. Wie wird das in anderen Programmen gemacht? Ich habe noch nie ein Programm gesehen, das einen solchen Hintergrund hat.
Versteh die Frage nicht recht. Bitte genauer erklären was du meinst.

Ich habe aber noch eine Alternative die aber ein wenig unsauberer ist.
Moment ich schreib das mal kurz...
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Leonidas hat geschrieben:Nein, in der Regel reicht es einfach ein wx.Panel in den wx.Frame zu knallen und dort dann die Widgets anzuordnen.
Exakt. Genau das meinte ich mit meinen anderen Vorschlag. Da hatten wir den gleichen Gedanken ^^

Code: Alles auswählen

import wx
        
class MainFrame(wx.Frame):
    def __init__(self, parent=None, id=-1, title = "MyApp"):
         wx.Frame.__init__(self, parent, id, title)
         
         # Der wxPanel im wxFrame. Alle weiteren Widgets sollten dann 
         # Natürlich die Instanz vom wxPanle als Parent bekommen.
         # In dem beispiel halt bg.
         bg = wx.Panel(self)
         
         
                  
def main():
    app = wx.PySimpleApp()
    mf =  MainFrame()
    mf.Show()
    app.MainLoop()

if __name__ == "__main__":
    main()
Zuletzt geändert von sape am Freitag 22. Dezember 2006, 14:21, insgesamt 1-mal geändert.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

sape hat geschrieben:Du installierst dir ein Programm wie Gimp und suchst dir den Farbton aus den du haben möchtest. Es wird dir bei der Farbauswahl immer die RGB Werte angezeigt. Diese Trägst du dann ein.

Ich persönlich würde aber keine Feste Vorgabe von Farbwerten in der Applikation einprogrammieren, sondern es dem OS überlassen. Das sorgt für ein einhaltliches Design aller Applikationen.
Hä? Ich denke du widersprichst dir grad selbst: erst sagst du, dass es nur per Farbeingabe geht und dann sagst du dasss man das dem OS überlassen soll.

Natürlich soll man sowas dem Toolkit überlassen! Dafür ist es ja auch da, und einige GTK-Engines ignorieren Farben auf bestimmten Widgets generell.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
basti33
User
Beiträge: 56
Registriert: Donnerstag 24. August 2006, 15:05

Und wieso ist die Lösung mit dem wx.Panel jetzt "unsauber"?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

basti33 hat geschrieben:Und wieso ist die Lösung mit dem wx.Panel jetzt "unsauber"?
Sie ist IMHO gar nicht unsauber.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Leonidas hat geschrieben:[...]
Hä? Ich denke du widersprichst dir grad selbst: erst sagst du, dass es nur per Farbeingabe geht und dann sagst du dasss man das dem OS überlassen soll.
Nein. Ich habe nur auf seine erste Frage eine der Frage entsprechende Antwort gegeben! Ob ich das für richtig halte oder nicht sei dahingestellt, das es nicht darum ging. Ich habe es lediglich trotzdem später erwähnt um ihn darüber in Kenntnis zu setzen wie ich den Vorgang betrachte (und die Mehrheit). -> Ich es also als schlechten Stil ansehe.

Denoch habe ich trotzdem eine der Frage entsprechende Antwort geliefert. Wenn es um ``global`` geht würde ich auch dementsprechende antworten __aber__ mit den gleichen Vorbehalt wie hier -> Z.B. "So und so geht es mit global, aber lass trotzdem die Finger von ``global`` weile es ein schlechter Stil ist" ;)
Leonidas hat geschrieben:[...]
Natürlich soll man sowas dem Toolkit überlassen!
Korrekt!
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Leonidas hat geschrieben:
basti33 hat geschrieben:Und wieso ist die Lösung mit dem wx.Panel jetzt "unsauber"?
Sie ist IMHO gar nicht unsauber.
Jain. Ist es eigentlich nicht, bis auf die Tatsache das man nun das wxPanel als Parent nutzen muss (Und das nur obwohl wir dioch nur die Hintergrundfarbe ändern wollen, bzw. von nem ``wxPanel`` habe wollen)

Code: Alles auswählen

class MainFrame(wx.Frame):
    def __init__(self, parent=None, id=-1, title = "MyApp"):
         wx.Frame.__init__(self, parent, id, title)
         self.bg = wx.Panel(self)
         
         txt1 = wx.TextCtrl(self.bg)
         txt2 = wx.TextCtrl(self.bg, pos=(120, 0))
Die sauberste Lösung um das Hintergrundfarbe von einem ``wxPanel`` zu erhalten, ohne eines zu erzeugen und ohne es als Parent benutzen zu müssen ist folgende:

Code: Alles auswählen

class MainFrame(wx.Frame):
    def __init__(self, parent=None, id=-1, title = "MyApp"):
         wx.Frame.__init__(self, parent, id, title)
         # ``wx.Panel(self).GetBackgroundColour()`` hohlt die RGB-Werte
         # von dem wxPanel. ``self.SetBackgroundColour(...)`` setzt die
         # Hintergrundfarbe neu mit den geholten RGB-Werten.
         self.SetBackgroundColour(wx.Panel(self).GetBackgroundColour())
         
         # ``self`` kann weiterhin als Parent genutzt werden :)
         txt1 = wx.TextCtrl(self)
         txt2 = wx.TextCtrl(self, pos=(120, 0))
Wir wollen doch nur die RGB-Werte von einem non-wxFrame haben und wir wollen ``self`` doch weiterhin als Parent für darüberliegende Widgets nutzen. Wozu dann extra ein ``wx.Panel`` Instanz erzeugen und uns diese Instanz als Parent aufzwinge lassen __nur__ wegen der Hintergrundfarbe :)

Das ist meiner Meinung nach die sauberste und direkteste Lösung.

lg
sape
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hi!

Jetzt muss ich doch eingreifen. :?

Wer es noch nicht wusste --> nehmt es als vorgegeben hin:

Code: Alles auswählen

     Frame 
       |
     Panel
       |
sonstige Widgets (z.B. wx.StaticText)
Auf ein Frame gehört ein Panel, damit unter allen unterstützten Betriebssystemen ein Fenster wie ein dort übliches Fenster aussieht.

Es gibt natürlich Ausnahmen. Z.B. ``wx.Notebook`` oder ``wx.SplitterWindow``.

Ein Panel ist z.B. auch dafür verantwortlich, dass man mit der TAB-Taste von einem Widget zum nächsten wechseln kann. Willst du einen Standard-Button definieren -- brauchst du Panels. Willst du mehr Code wiederverwenden können -- brauchst du Panels.

mfg
Gerold
:-)

PS: wxPython in Action - Seite 227.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

gerold hat geschrieben: Ein Panel ist z.B. auch dafür verantwortlich, dass man mit der TAB-Taste von einem Widget zum nächsten wechseln kann.
Das ist natürlich ein Argument.

lg
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Hmm... Der Thread ist ja nun schon fast 3 Jahre alt, ich hoffe mal, dass meine Frage überhaupt noch von jemandem registriert wird... :-)

Die Gründe, weshalb ein Panel quasi als "Container" der Widgets verwendet werden soll, sind mir mehr oder weniger bekannt. Allerdings verstehe ich nicht, weshalb denn überhaupt ein Panel definiert werden muss. Gibt es auch manchmal einen Grund, kein Panel zu definieren? Ich kann den genauen Unterschied zwischen Frame und Panel nicht erkennen. Weshalb ist innerhalb eines Frames nicht gleich automatisch ein Panel angelegt?

Liebe Grüße
mutetellla
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Antworten