Font.measure

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Gibt es in wxPython eine zu Font.measure in Tkinter ähnliche Funktion, um bei bekanntem Font die Größe eines Strings zu bestimmen? Ich möchte möglichst nicht unnötig einen StaticText anlegen, um dann die ungefähre Textbreite mit GetSize() abzufragen. Die Texte befinden sich als RowLabel in einem wx.grid.Grid. Da es scheinbar kein Autosize für die Labels gibt, möchte ich die RowLabelSize dynamisch aus den Labels berechnen.
MfG
HWK
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

wenn ich dich richtig verstanden ahbe sollte dies für dich genügen

grid.AutoSizeColLabelSize(1)

http://www.wxpython.org/docs/api/wx.gri ... class.html
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Klingt gut, funktioniert aber irgendwie nicht richtig:

Code: Alles auswählen

from random import randrange
import wx
import wx.grid as gridlib

class FastGrid(gridlib.Grid):
    def __init__(self, parent, row=10, col=10):
        gridlib.Grid.__init__(self, parent, -1)
        self.CreateGrid(row, col)
        self.EnableEditing(False)
        self.EnableGridLines(False)
        self.DisableDragGridSize()
        self.SetDefaultCellAlignment(wx.ALIGN_RIGHT, wx.ALIGN_CENTRE)
        for i in range(col):
            self.SetColLabelValue(i, 'Spalte %i' % i)
        for i in range(row):
            self.SetRowLabelValue(i, 'Riesenreihe %i' % i)
            for j in range(col):
                self.SetCellValue(i, j, str(randrange(100000000)))
            self.SetCellTextColour(i, j, 'Red')
        self.AutoSize()
        self.AutoSizeColLabelSize(1)
        self.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnSelectCell)
        self.Bind(wx.grid.EVT_GRID_RANGE_SELECT, self.OnRangeSelect)
        wx.CallAfter(self.initial_scroll, i, j)

    def initial_scroll(self, row, col):
        self.MakeCellVisible(row, col)

    def OnSelectCell(self, evt): 
        evt.Veto()

    def OnRangeSelect(self, evt): 
        self.ClearSelection()

app = wx.PySimpleApp()
frame = wx.Frame(None, -1, 'FastGrid', size=(500, 500))
FastGrid(frame, 20, 100) # <- Hier andere Groessen eingeben
frame.Show()
app.MainLoop()
Ich hab's auch mit anderen Parametern und mit AutoSizeRowLabelSize versucht. Das Ergebnis ist genauso enttäuschend. Die Doku ist leider auch wenig hilfreich. Was mache ich denn verkehrt?
Danke
HWK
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

Mir fällt gerade auf, dass ich in meinem Programm

Code: Alles auswählen

self.AutoSizeColumns()
verwende (self ist ein wx.grid.Grid)
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Das funktioniert genausowenig. AutoSizeColumns und AutoSizeRows wirken sich nur auf die Zellen und nicht die Labels aus. Das AutoSize in meinem Script müßte eigentlich AutoSizeColumns und AutoSizeRows enthalten.
MfG
HWK
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Ich habe jetzt die Funktion von AutoSizeColLabelSize und AutoSizeRowLabelSize geklärt. AutoSizeColLabelSize ändert scheinbar die Labelbreite nur der angegebenen Spalte, AutoSizeRowLabelSize die Labelhöhe nur der angegebenen Reihe. Es ist somit wohl nicht möglich, die RowLabel-Breite automatisch zu ändern. Deshalb noch einmal zurück zur Ausgangsfrage: Gibt es eine Möglichkeit, die Breite eines Strings bei bekanntem Font zu bestimmen? Dann könnte ich die Breite ja auch dynamisch festlegen: SetRowLabelSize(Maximale_Breite)
MfG
HWK
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

Code: Alles auswählen

    def GetBestSize( self, grid, attr, dc, row, col ):

        """Beste Grösse ermitteln"""

        table = grid.GetTable()

        text = table.GetValue( row, table.GetNumberCols() )

        text = str(text.get_date())    

        w, h = dc.GetTextExtent( text )

        return wx.Size( w, h )
So habe ich das bei meinen Renderer gemacht.

mit dc.GetTextExtent(text) bekommt man die höhe / Breite
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Super!
Funktioniert sehr gut. Hier ist das entsprechende Test-Script:

Code: Alles auswählen

from random import randrange
import wx
import wx.grid as gridlib

class FastGrid(gridlib.Grid):
    def __init__(self, parent, row=10, col=10):
        gridlib.Grid.__init__(self, parent, -1)
        self.CreateGrid(row, col)
        self.EnableEditing(False)
        self.EnableGridLines(False)
        self.DisableDragGridSize()
        self.SetDefaultCellAlignment(wx.ALIGN_RIGHT, wx.ALIGN_CENTRE)
        dc = wx.ClientDC(parent)
        max_width = 0
        for i in range(col):
            self.SetColLabelValue(i, 'Spalte %i' % i)
        for i in range(row):
            self.SetRowLabelValue(i, 'Riesenreihe %i' % i)
            max_width = max(max_width,
                            dc.GetTextExtent('Riesenreihe %i' % i)[0])
            for j in range(col):
                self.SetCellValue(i, j, str(randrange(100000000)))
            self.SetCellTextColour(i, j, 'Red')
        self.AutoSize()
        self.SetRowLabelSize(max_width)
        self.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnSelectCell)
        self.Bind(wx.grid.EVT_GRID_RANGE_SELECT, self.OnRangeSelect)
        wx.CallAfter(self.initial_scroll, i, j)

    def initial_scroll(self, row, col):
        self.MakeCellVisible(row, col)

    def OnSelectCell(self, evt): 
        evt.Veto()

    def OnRangeSelect(self, evt): 
        self.ClearSelection()

app = wx.PySimpleApp()
frame = wx.Frame(None, -1, 'FastGrid', size=(500, 500))
FastGrid(frame, 20, 100) # <- Hier andere Groessen eingeben
frame.Show()
app.MainLoop()
Danke
HWK
Antworten