Seite 1 von 2

*Gelöst* Listicongadget quälend langsam

Verfasst: 29.06.2023 21:41
von Led Zep
Moin allerseits!
Habe ein Listicongadget, 17 Spalten, rund 105 Zeilen. Das Listicongadget füllt das ganze Fenster, beim "Resizen" des Fensters wird das Gadget ebenfalls angepasst, die Spaltenbreite dann neu berechnet und entsprechend justiert (alle Spalten gleich breit).

Allerdings ist das beim "Resizen" dann quälend langsam. Ich kann zusehen, wie Spalte für Spalte verändert wird. Kratzen 17 x 105 Zellen schon an der Leistungsgrenze?

Habe ein gewisses Talent darin, Anfängerfehler zu machen und schrecke auch vor den Dümmsten nicht zurück! Gibt's da einen typischen Anfängerfehler, der sich dann so äußert?

Re: Listicongadget quälend langsam

Verfasst: 29.06.2023 21:49
von jacdelad
Also die Menge an Daten sollte eigentlich kein Problem sein. Kannst du einen funktionierenden (!) Quellcode zur Verfügung stellen, damit wir den testen können? Vielleicht hakt's da irgendwo.

Ansonsten (nur Windows):
- Virtuelles ListView verwenden (das ist aber recht fortgeschritten)
- mit SendMessage_(GadgetID(MeinListIcon),#WM_SETREDRAW,0,0) vor und SendMessage_(GadgetID(MeinListIcon),#WM_SETREDRAW,1,0) nach dem Resize-Vorgang experimentieren

Wie gesagt, am besten du schickst uns mal einen Code, damit wir den zerpflücken können. Als Daten kannst du ja mit einer Schleife Zufallsdaten erzeugen.

Re: Listicongadget quälend langsam

Verfasst: 29.06.2023 22:04
von HeX0R
Ein virtuelles ListView wäre ja wohl doch etwas übertrieben für die paar Zeilen.

Re: Listicongadget quälend langsam

Verfasst: 29.06.2023 22:50
von jacdelad
Sicher, aber kommt darauf an, warum es so langsam ist. Deswegen hoffe ich auf einen Code, der das demonstriert.

Re: Listicongadget quälend langsam

Verfasst: 30.06.2023 08:32
von Led Zep
Hallo,

hier mein Programm auf das notwendigste eingedampft. Wenn man horizontal "Resized", werden die Spaltenbreiten recht gemütlich angepasst. Man sieht andere Listicongadgets mit mehr Daten, da geht das deutlich zackiger ...

Code: Alles auswählen

Enumeration
  #parent
  #font1
  #lig
  #menu
  #csb
EndEnumeration

Procedure updateLig()
  ResizeGadget(#lig, 0, 0, WindowWidth(#parent), WindowHeight(#parent)-StatusBarHeight(#csb)-MenuHeight())
  korrekturwert = 2
  If GetWindowLongPtr_(GadgetID(#lig), #GWL_STYLE) & #WS_VSCROLL    ;wenn scrollbalken vorhanden
    korrekturwert = 4 + GetSystemMetrics_(#SM_CXVSCROLL)            ;dann Bereich für die Spalten reduzieren
  EndIf
  MaxColWidth = GadgetWidth(#lig) - korrekturwert
  cols = GetGadgetAttribute(#lig, #PB_ListIcon_ColumnCount)
  x = MaxColWidth/cols : rest = MaxColWidth
  For i = 0 To cols-2     ;Platz für erste bis vorletzte Spalte verteilen
    SetGadgetItemAttribute(#lig, #PB_Ignore, #PB_ListIcon_ColumnWidth, x, i)
    rest - x
  Next
  SetGadgetItemAttribute(#lig, #PB_Ignore, #PB_ListIcon_ColumnWidth, rest ,cols-1)  ; Rest für die letzte Spalte
EndProcedure

; initialisieren
winflags = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered
ligflags = #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection

;- openwindow
OpenWindow(#parent,0,0,1200,700,"Tabelle",winflags)
LoadFont(#font1, "Arial", 11) : SetGadgetFont(#PB_Default, FontID(#font1))

;- Menu
If CreateMenu(#menu, WindowID(#parent))
  MenuTitle("Tabelle")
  MenuItem(101, "Tabelle")
EndIf

;- Statusbar
CreateStatusBar(#csb, WindowID(#parent))
AddStatusBarField(100)
AddStatusBarField(#PB_Ignore)
AddStatusBarField(#PB_Ignore)
StatusBarText(#csb, 0, "")
StatusBarText(#csb, 1, "")

;- LIG
ListIconGadget(#lig, 0, 0, WindowWidth(#parent), WindowHeight(#parent), "A", 10, ligflags)
AddGadgetColumn(#lig, 1, "B", 10)
AddGadgetColumn(#lig, 2, "C", 10)
AddGadgetColumn(#lig, 3, "D", 10)
AddGadgetColumn(#lig, 4, "E", 10)
AddGadgetColumn(#lig, 5, "F", 10)
AddGadgetColumn(#lig, 6, "G", 10)
AddGadgetColumn(#lig, 7, "H", 10)
AddGadgetColumn(#lig, 8, "I", 10)
AddGadgetColumn(#lig, 9, "J", 10)
AddGadgetColumn(#lig, 10, "K", 10)
AddGadgetColumn(#lig, 11, "L", 10)
AddGadgetColumn(#lig, 12, "M", 10)
AddGadgetColumn(#lig, 13, "N", 10)
AddGadgetColumn(#lig, 14, "O", 10)
AddGadgetColumn(#lig, 15, "P", 10)
AddGadgetColumn(#lig, 16, "Q", 10)

x$ = ""
For i = 0 To 15
  x$ + "Blutwurst" + Chr(10)
Next
x$ + "Blutwurst"

For i = 0 To 105
  AddGadgetItem(#lig, -1, x$)
Next

updateLig()

;- ********** Event ************
Repeat
  event = WaitWindowEvent()
  Gadget = EventGadget()
  
  Select event
    Case #PB_Event_CloseWindow
      Select EventWindow()
        Case #parent
          End
      EndSelect
      
    Case #PB_Event_SizeWindow
      ResizeGadget(#lig,0,0,WindowWidth(#parent),WindowHeight(#parent))
      updateLig()
      
    Case #PB_Event_Menu
      Select EventMenu()
        Case 101
      EndSelect
  EndSelect
  
  Select Gadget
    Case #lig
      Select EventType()
        Case #PB_EventType_Change
        Case #PB_EventType_DragStart
        Case #PB_EventType_LeftClick
        Case #PB_EventType_LeftDoubleClick
          SetGadgetState(Gadget, -1)
        Case #PB_EventType_RightClick
          SetGadgetState(Gadget, -1)
        Case #PB_EventType_RightDoubleClick
          SetGadgetState(Gadget, -1)
      EndSelect
      
  EndSelect
ForEver
End

Re: Listicongadget quälend langsam

Verfasst: 30.06.2023 08:58
von mk-soft
Das ReDraw von ListIconGadget sperren und wieder freigeben ...

Code: Alles auswählen

Enumeration
  #parent
  #font1
  #lig
  #menu
  #csb
EndEnumeration

Procedure updateLig()
  ResizeGadget(#lig, 0, 0, WindowWidth(#parent), WindowHeight(#parent)-StatusBarHeight(#csb)-MenuHeight())
  korrekturwert = 2
  If GetWindowLongPtr_(GadgetID(#lig), #GWL_STYLE) & #WS_VSCROLL    ;wenn scrollbalken vorhanden
    korrekturwert = 4 + GetSystemMetrics_(#SM_CXVSCROLL)            ;dann Bereich für die Spalten reduzieren
  EndIf
  MaxColWidth = GadgetWidth(#lig) - korrekturwert
  cols = GetGadgetAttribute(#lig, #PB_ListIcon_ColumnCount)
  x = MaxColWidth/cols : rest = MaxColWidth
  For i = 0 To cols-2     ;Platz für erste bis vorletzte Spalte verteilen
    SetGadgetItemAttribute(#lig, #PB_Ignore, #PB_ListIcon_ColumnWidth, x, i)
    rest - x
  Next
  SetGadgetItemAttribute(#lig, #PB_Ignore, #PB_ListIcon_ColumnWidth, rest ,cols-1)  ; Rest für die letzte Spalte
EndProcedure

; initialisieren
winflags = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered
ligflags = #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection

;- openwindow
OpenWindow(#parent,0,0,1200,700,"Tabelle",winflags)
LoadFont(#font1, "Arial", 11) : SetGadgetFont(#PB_Default, FontID(#font1))

;- Menu
If CreateMenu(#menu, WindowID(#parent))
  MenuTitle("Tabelle")
  MenuItem(101, "Tabelle")
EndIf

;- Statusbar
CreateStatusBar(#csb, WindowID(#parent))
AddStatusBarField(100)
AddStatusBarField(#PB_Ignore)
AddStatusBarField(#PB_Ignore)
StatusBarText(#csb, 0, "")
StatusBarText(#csb, 1, "")

;- LIG
ListIconGadget(#lig, 0, 0, WindowWidth(#parent), WindowHeight(#parent), "A", 10, ligflags)

SendMessage_(GadgetID(#lig), #WM_SETREDRAW, 0, 0)

AddGadgetColumn(#lig, 1, "B", 10)
AddGadgetColumn(#lig, 2, "C", 10)
AddGadgetColumn(#lig, 3, "D", 10)
AddGadgetColumn(#lig, 4, "E", 10)
AddGadgetColumn(#lig, 5, "F", 10)
AddGadgetColumn(#lig, 6, "G", 10)
AddGadgetColumn(#lig, 7, "H", 10)
AddGadgetColumn(#lig, 8, "I", 10)
AddGadgetColumn(#lig, 9, "J", 10)
AddGadgetColumn(#lig, 10, "K", 10)
AddGadgetColumn(#lig, 11, "L", 10)
AddGadgetColumn(#lig, 12, "M", 10)
AddGadgetColumn(#lig, 13, "N", 10)
AddGadgetColumn(#lig, 14, "O", 10)
AddGadgetColumn(#lig, 15, "P", 10)
AddGadgetColumn(#lig, 16, "Q", 10)


x$ = ""
For i = 0 To 15
  x$ + "Blutwurst" + Chr(10)
Next
x$ + "Blutwurst"

For i = 0 To 105
  AddGadgetItem(#lig, -1, x$)
Next

updateLig()

SendMessage_(GadgetID(#lig), #WM_SETREDRAW, 1, 0)

;- ********** Event ************
Repeat
  event = WaitWindowEvent()
  Gadget = EventGadget()
  
  Select event
    Case #PB_Event_CloseWindow
      Select EventWindow()
        Case #parent
          End
      EndSelect
      
    Case #PB_Event_SizeWindow
      ResizeGadget(#lig,0,0,WindowWidth(#parent),WindowHeight(#parent))
      SendMessage_(GadgetID(#lig), #WM_SETREDRAW, 0, 0)
      updateLig()
      SendMessage_(GadgetID(#lig), #WM_SETREDRAW, 1, 0)
      
      ;FitColumnWidth(#lig)
    Case #PB_Event_Menu
      Select EventMenu()
        Case 101
      EndSelect
  EndSelect
  
  Select Gadget
    Case #lig
      Select EventType()
        Case #PB_EventType_Change
        Case #PB_EventType_DragStart
        Case #PB_EventType_LeftClick
        Case #PB_EventType_LeftDoubleClick
          SetGadgetState(Gadget, -1)
        Case #PB_EventType_RightClick
          SetGadgetState(Gadget, -1)
        Case #PB_EventType_RightDoubleClick
          SetGadgetState(Gadget, -1)
      EndSelect
      
  EndSelect
ForEver
End

Re: *Gelöst* Listicongadget quälend langsam

Verfasst: 30.06.2023 09:52
von Led Zep
Hammermäßig!
Heute früh den Beispielcode hochgeladen und nur wenige Minuten später: BÄNG! Problem gelöst!

Mit

Code: Alles auswählen

SendMessage_(GadgetID(MeinListIcon),#WM_SETREDRAW,0,0)
;
;
;
SendMessage_(GadgetID(MeinListIcon),#WM_SETREDRAW,1,0)
läuft's jetzt so "zackig", wie man's sich gedacht hätte.

Vielen Dank Euch allen!

Re: *Gelöst* Listicongadget quälend langsam

Verfasst: 30.06.2023 14:41
von jacdelad
Genau so meinte ich das.
@mk-soft: Gibt's sowas auch für Linux und Mac? Das wäre doch mal eine kleine Funktion wert, das Problem tritt ja immer mal wieder auf.

Re: *Gelöst* Listicongadget quälend langsam

Verfasst: 03.07.2023 10:13
von dige
Bei so wenig Zeilen / Reihen vermute ich aber auch ein Problem mit dem Event-Loop. Ich lasse nach Resize Events deshalb gern mal ein While WindowEvent() : Wend durchlaufen. Das beschleunigt das neuzeichnen von allen UI Elementen..

Re: *Gelöst* Listicongadget quälend langsam

Verfasst: 03.07.2023 14:09
von jacdelad
dige hat geschrieben: 03.07.2023 10:13 Bei so wenig Zeilen / Reihen vermute ich aber auch ein Problem mit dem Event-Loop. Ich lasse nach Resize Events deshalb gern mal ein While WindowEvent() : Wend durchlaufen. Das beschleunigt das neuzeichnen von allen UI Elementen..
Gehen da nicht aber möglicherweise wichtige Events verloren, wenn die schnell danach folgen?