Rhazz

How to configure a GUI Progress Bar by a double "for" loop

8 posts in this topic

#1 ·  Posted (edited)

Hello again, my second post in 24 hs! :P

It's my first GUI... and my first progress bar also! Sorry if I make a newbie mistake.

I want to configure a GUI Progress Bar by a double "for" loop.

Here is my code with a specific annotation with what I want to do:

Edit: new problem, I have no idea how can I continue with the next $a as if the current $a, I do not skip it because the line is an element less (I need help with both problems):

#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <WinAPI.au3>
#include <File.au3>
#include <String.au3>
#include <Array.au3>


Local $idGUI = GUICreate("ProgressBar", 220, 130, 100, 200)
Opt("GUIOnEventMode", 1)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEButton")
Local $idInput = GUICtrlCreateInput("",80,20,60,20,$ES_NUMBER)
Local $idProgressBar = GUICtrlCreateProgress(10, 60, 200, 20)
Local $idButton1 = GUICtrlCreateButton("Start",85,100,50)
GUICtrlSetOnEvent($idButton1, "StartProgressBar")
Local $aFileOpen = _WinAPI_GetOpenFileName("Open a text file", "Text Files (*.txt)")
Local $idCountLines = _FileCountLines($aFileOpen[2])
Local $idInputValue, $idSomething, $aFileResult, $idStringBetween

GUISetState(@SW_SHOW, $idGUI)
While 1
    Sleep(20000)
WEnd

Func StartProgressBar()
    If StringInStr($aFileOpen[2], ".txt") = True Then
        $idInputValue = Int(GUICtrlRead($idInput))
        If IsFloat($idCountLines/$idInputValue) = 1 Then
            $idStringBetween = _StringBetween(String($idCountLines/$idInputValue),"", ".")
            $idSomething = Number($idStringBetween[0]) + 1
        Else
            $idSomething = $idCountLines/$idInputValue
        EndIf
        For $i = 1 To $idSomething
            $aFileResult = @ScriptDir & "\result-" & $i & ".txt"
            _FileCreate($aFileResult)
            FileOpen($aFileResult,2)
            For $a = ( ( ( $i - 1 ) * $idInputValue ) + 1 ) To ( $i * $idInputValue )
                If FileReadLine($aFileOpen[2], $a) = "" Then
                    ; Here I have no idea how can I continue with the next $a as if the current $a, I do not skip it because the line is an element less
                EndIf
                FileWrite($aFileResult,FileReadLine($aFileOpen[2], $a) & " - ")
                ;Here I want to set the progress bar value = current percentage (line that it is currently reading) of the 100% (total of lines in the file opened)
            Next
            FileClose($aFileResult)
        Next
        MsgBox(0,"Done","Done")
        GUICtrlSetData($idProgressBar,0)
    Else
        MsgBox(0,"Hello :)","Please open a file :D")
    EndIf
EndFunc

Func CLOSEButton()
    Exit
EndFunc

 

Thanks in advance.

 

Edited by Rhazz
New problem added

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

First you need to get the percentage based on the multiplication of loop ($i*$a) real loops.  then divide  progressbar size by that multiplication.

100/($i*$a) that will result that number of necessary movement that you will use on loop. Finally you will get something like this.

#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 374, 115, 192, 124)
$Progress1 = GUICtrlCreateProgress(16, 24, 345, 49)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

Local $i=300-100
Local $a=200
Local $imove=100/($i*$a)
Local $itemp=0


For $i= 100 to 300
    For $a=1 to 200
        $itemp+=$imove
        GUICtrlSetData($Progress1,$itemp)
        ;for continue with the next $a just use ContinueLoop
    Next
    $itemp+=$imove
    GUICtrlSetData($Progress1,$itemp)

Next

ConsoleWrite($itemp & @CRLF)


While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd
 

Saludos

Edited by Danyfirex

Share this post


Link to post
Share on other sites

First you need to get the percentage based on the multiplication of loop ($i*$a) real loops.  then divide  progressbar size by that multiplication.

100/($i*$a) that will result that number of necessary movement that you will use on loop. Finally you will get something like this.

#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 374, 115, 192, 124)
$Progress1 = GUICtrlCreateProgress(16, 24, 345, 49)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

Local $i=300-100
Local $a=200
Local $imove=100/($i*$a)
Local $itemp=0


For $i= 100 to 300
    For $a=1 to 200
        $itemp+=$imove
        GUICtrlSetData($Progress1,$itemp)
        ;for continue with the next $a just use ContinueLoop
    Next
    $itemp+=$imove
    GUICtrlSetData($Progress1,$itemp)

Next

ConsoleWrite($itemp & @CRLF)


While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd
 

Saludos

Spanish: Veo que hablás español, así que hola! "ContinueLoop" salta la linea del primer archivo y no la agrega a la linea del segundo archivo, ejemplo:

  • Línea 1 - Línea 2 - Línea 3 -
  • Línea 5 - Línea 6 - Línea 7- Línea 8 -

Si te fijas, saltó la línea 4 (suponiendo que está vacía). Igualmente tengo que mirarlo con detenimiento para ver qué puedo hacer, pero no he tenido tiempo.

 

English: Hi, with ContinueLoop the script skips the empty line (of the first file) and therefore there is an element less in the line of the second file (the empty line of the first file becomes into empty space in the second file). e.g. the user wants four lines (of the 1st file) per line (of the 2nd file) and the fourth line (of the 1st file) is empty:

  • Line 1 - Line 2 - Line 3 -
  • Line 5 - Line 6 - Line 7 - Line 8

In the first line there is an element less.Whatever, I have to try it again, these days I didn't have much time.

Share this post


Link to post
Share on other sites

Si fijate en la ayuda y notaras un ejemplo que continueloop esquiva un determinado loop.

Yes look into help file and you will notice an example that continuwloop avoid a determined loop.

 

Saludos

Share this post


Link to post
Share on other sites

Si fijate en la ayuda y notaras un ejemplo que continueloop esquiva un determinado loop.

Yes look into help file and you will notice an example that continuwloop avoid a determined loop.

 

Saludos

I said that ContinueLoop doesn't work, I want to skip a line, not skip a loop. Sorry if I didn't explain me well. Here are another example with the code:

#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <WinAPI.au3>
#include <File.au3>
#include <String.au3>
#include <Array.au3>


Local $idGUI = GUICreate("ProgressBar", 220, 130, 100, 200)
Opt("GUIOnEventMode", 1)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEButton")
Local $idInput = GUICtrlCreateInput("",80,20,60,20,$ES_NUMBER)
Local $idProgressBar = GUICtrlCreateProgress(10, 60, 200, 20)
Local $idButton1 = GUICtrlCreateButton("Start",85,100,50)
GUICtrlSetOnEvent($idButton1, "StartProgressBar")
Local $aFileOpen = _WinAPI_GetOpenFileName("Open a text file", "Text Files (*.txt)")
Local $idCountLines = _FileCountLines($aFileOpen[2])
Local $idInputValue, $idSomething, $aFileResult, $idStringBetween

GUISetState(@SW_SHOW, $idGUI)
While 1
    Sleep(20000)
WEnd

Func StartProgressBar()
    If StringInStr($aFileOpen[2], ".txt") = True Then
        $idInputValue = Int(GUICtrlRead($idInput))
        If IsFloat($idCountLines/$idInputValue) = 1 Then
            $idStringBetween = _StringBetween(String($idCountLines/$idInputValue),"", ".")
            $idSomething = Number($idStringBetween[0]) + 1
        Else
            $idSomething = $idCountLines/$idInputValue
        EndIf
        For $i = 1 To $idSomething
            $aFileResult = @ScriptDir & "\result-" & $i & ".txt"
            _FileCreate($aFileResult)
            FileOpen($aFileResult,2)
            For $a = ( ( ( $i - 1 ) * $idInputValue ) + 1 ) To ( $i * $idInputValue )
                If FileReadLine($aFileOpen[2], $a) = "" Then
                    ; ContinueLoop
                    ; Here I have no idea how can I continue with the next $a as if the current $a, I do not skip it because the line is an element less
                EndIf
                GUICtrlSetData($idProgressBar, (100/($i*$a)))
                MsgBox(0,"",(100/($i*$a)))
                FileWrite($aFileResult,FileReadLine($aFileOpen[2], $a) & " - ")
                ; Here I want to set the progress bar value = current percentage (line that it is currently reading) of the 100% (total of lines in the file opened)
            Next
            FileClose($aFileResult)
        Next
        MsgBox(0,"Done","Done")
        Sleep(5000)
        GUICtrlSetData($idProgressBar,0)
    Else
        MsgBox(0,"Hello :)","Please open a file :D")
    EndIf
EndFunc

Func CLOSEButton()
    Exit
EndFunc

With a first text file that contains:

Line1
Line2
Line3
Line4

Line6
Line7
Line8
Line9
Line10
Line11
Line12

And if the user introduces "6" the result is:

  • result-1.txt --> Line1 - Line2 - Line3 - Line4 - Line6 - (five lines, the user wants six)
  • result-2.txt --> Line7 - Line8 - Line9 - Line10 - Line11 - Line12 - (six lines, great)

I have been reading the Help File and I think that there are two options that might work:

  1. Read the text file and create a temporary file without blank lines, and use it to create the final text file.
  2. Try to use _FileReadToArray

What do you think about it? What is most effectively? Are there a better option?

And with that code, the progress bar works wrong :s I didn't find the correct operation, I think that might it works with _FileReadToArray (the total of it would be 100% and the current row/position would be the current percentage).

PS: I also think maybe using _FileReadToArray might be too much work for big text files... I'm wrong?

Share this post


Link to post
Share on other sites

Simply check for a not empty line. also create a variable counter to plus one every time that is not emply line instead using $i.

 

Saludos

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Simply check for a not empty line. also create a variable counter to plus one every time that is not emply line instead using $i.

 

Saludos

That doesn't work because I need to exclude the empty lines, but what you say will return the numbers of non-empty lines and the script will read that numbers of lines but without skip the blank lines.

A good news: Finally I could set the progress bar! It works now! I used "Total Of Lines" / ("Current Line" * 100)

Finally I got the solution!!!!

I created another variable to set what line have to read the script. Here is my full code, I hope be helpful for somebody :)

#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <WinAPI.au3>
#include <File.au3>
#include <String.au3>
#include <Array.au3>


Local $idGUI = GUICreate("ProgressBar", 220, 130, 100, 200)
Opt("GUIOnEventMode", 1)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEButton")
Local $idInput = GUICtrlCreateInput("",80,20,60,20,$ES_NUMBER)
Local $idProgressBar = GUICtrlCreateProgress(10, 60, 200, 20)
Local $idButton1 = GUICtrlCreateButton("Start",85,100,50)
GUICtrlSetOnEvent($idButton1, "StartProgressBar")
Local $aFileOpen = _WinAPI_GetOpenFileName("Open a text file", "Text Files (*.txt)")
Local $idCountLines = _FileCountLines($aFileOpen[2])
Local $idInputValue, $idSomething, $aFileResult, $idStringBetween, $LineToRead, $totalNonEmptyLines
For $y = 1 To $idCountLines
    If FileReadLine($aFileOpen[2],$y) <> "" Then $totalNonEmptyLines += 1
Next


GUISetState(@SW_SHOW, $idGUI)
While 1
    Sleep(20000)
WEnd

Func StartProgressBar()
    If StringInStr($aFileOpen[2], ".txt") = True Then
        $idInputValue = Int(GUICtrlRead($idInput))
        If IsFloat($totalNonEmptyLines/$idInputValue) = 1 Then
            $idStringBetween = _StringBetween(String($totalNonEmptyLines/$idInputValue),"", ".")
            $idSomething = Number($idStringBetween[0]) + 1
        Else
            $idSomething = $totalNonEmptyLines/$idInputValue
        EndIf
        For $i = 1 To $idSomething
            $aFileResult = @ScriptDir & "\result-" & $i & ".txt"
            _FileCreate($aFileResult)
            FileOpen($aFileResult,2)
            For $a = ( ( ( $i - 1 ) * $idInputValue ) + 1 ) To ( $i * $idInputValue )
                $LineToRead += 1
                While FileReadLine($aFileOpen[2], $LineToRead) = ""
                    $LineToRead += 1
                    If $a = $idCountLines Then ExitLoop
                WEnd
                GUICtrlSetData($idProgressBar, (($LineToRead*100)/$totalNonEmptyLines))
                FileWrite($aFileResult,FileReadLine($aFileOpen[2], $LineToRead) & " - ")
            Next
            FileClose($aFileResult)
        Next
        MsgBox(0,"Done","Done")
        GUICtrlSetData($idProgressBar,0)
    Else
        MsgBox(0,"Hello :)","Please open a file :D")
    EndIf
EndFunc

Func CLOSEButton()
    Exit
EndFunc

 

Edited by Rhazz
Finally solved!

Share this post


Link to post
Share on other sites

This is an Old post but anyways here an Advise:

Why you dont use Round(), you will avoid unnecessary call to _StringBetween?
Your Code:

If IsFloat($totalNonEmptyLines/$idInputValue) = 1 Then
            $idStringBetween = _StringBetween(String($totalNonEmptyLines/$idInputValue),"", ".")
            $idSomething = Number($idStringBetween[0]) + 1

What I would probably do:
 

If IsFloat($totalNonEmptyLines/$idInputValue) = 1 Then
            $id = Round($totalNonEmptyLines/$idInputValue),0)
            $idnum = Number($id + 1)

This is just an Idea but I think is more efficient.

Kind Regards
Alien
 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Similar Content

    • fatpig
      By fatpig
      Dear AutoIT Community.
      I am currently working on a program that will display lots of images in a scroll down GUI.
      I create the GUI based on the number of images, which works fine.
      But all images I place using GuiCtrlCreatePic above a threshold of around 32000 pixels (cant say exactly) are placed at negative locations and finally will reach 0 again
      and will then populate on top of the images placed there before.
      For $i = 1 To $Images[0] ; Get picture dimensions $hImage = _GDIPlus_ImageLoadFromFile($ImgRep & $Images[$i]) $iX = _GDIPlus_ImageGetWidth($hImage) $iY = _GDIPlus_ImageGetHeight($hImage) _GDIPlus_ImageDispose($hImage) ; Resize & place images in GUI $Pic[$i] = GUICtrlCreatePic($ImgRep & $Images[$i], $Spacer, Round($yPos, 0), $MaxImgWidth, $MaxImgWidth * ($iY / $iX)) $yPos = $yPos + $MaxImgWidth * ($iY / $iX) + $Spacer $log = $log & "|" & $yPos $currentlut = $Images[1] Next I have found a limit at 32767 pixels for some GUI elements when googling around.
      Can someone tell me how to circumvent that?
      thanks!
      cheers
      Felix
    • Shirdish_chakravarthi
      By Shirdish_chakravarthi
      Hello Guys this is my gui and i need the numeric value typed in the highlighted  inputbox. if this value is greater than 1 i need to perform some operations
      \
       
      Here is the summary about that field which i got from wininfo tool

      i tried writing the code as shown below.. but the msgbox is popping up empty value..when the same code is pasted under some button action i am able to access the value present in the field..but when placed alone as written in the attached script i am unable to fetch it... 

      here i am using the valu present in the field

      can you guys tell me what's wrong??? or how can i get that value?
       
      My_GUI.au3

    • Neonovaz
      By Neonovaz
      Hello
       
      Is there anyway to store word documents in Autoit GUI? For example I have a instruction sheet that I want to bundle up with the exe.

      So a user simply clicks the icon and the stored document will launch  (Something like how you can add objects like excel sheets in word documents )

      (I Know we can launch word files from script directory)

       
    • hemichallenger
      By hemichallenger
      Not sure if this is possible or if someone has already tackled this. Is it possible to embed PowerShell into a GUI? Autoit is great for quick function but sometime I need to run a command thru PowerShell. It be great to have PowerShell console embedded into the gui.
    • 0Ethan0
      By 0Ethan0
      Ahoy Autoit Community!
      After many trials and errors I am unable to solve a problem I am facing and would appreciate any kind of input or better yet a solution 
      The Premise: An embeded slideshow viewer that runs after double-clicking an item in a ListView (each item will generate a different slideshow images).
      The Setup: GUI with a ListView Control and a simple exit button.
      The Issue: Once double clicked the slide plays however the GUI "locks"/non responsive until the slide is over. Same thing if I click on the "Test" button.
      The Culprit: I believe since it's in the images loop it can't accept any other commands until that loop is over.
      The Wish: I want to be able to use the GUI functions (selecting other items, clicking on button etc.) while the slideshow plays.
      The Code (stripped and simplified as much as I could):
      #include <GuiListView.au3> #include <File.au3> #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) HotKeySet("{Esc}", "_Exit") Global $c=0 Global $ssGDI[3], $ssGraphic[2], $ssImage Global Const $bg_color = "000000" Global Const $ssW = 480, $ssH = 320 Global $aFiles = _FileListToArrayRec("d:\testStage\", "*.jpg;*.png;*.bmp;*.gif;*.JPG;*.PNG;*.BMP;*.GIF", $FLTAR_FILES, $FLTAR_NORECUR ,$FLTAR_SORT ,$FLTAR_FULLPATH ) $guiW = 1200 $guiH = 726 $mainWindow = GUICreate("Slideshow Viewer", $guiW, $guiH, -1, -1, $WS_POPUP) $Button1 = GUICtrlCreateButton("Exit", 0, 0, 50, 50) GUICtrlSetOnEvent($Button1, "_Exit") $Button1 = GUICtrlCreateButton("Test", 60, 0, 50, 50) GUICtrlSetOnEvent($Button1, "Test") Global $ListView = GUICtrlCreateListView("Entry Name|Category", 5, 75, 195, 280) _GUICtrlListView_SetColumnWidth ($ListView, 0, 100) _GUICtrlListView_SetColumnWidth ($ListView, 1, 100) GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES) GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT) GUICtrlCreateListViewItem("Name 1|Category 1", $ListView) GUICtrlCreateListViewItem("Name 2|Category 2", $ListView) screenshotWidgetInit($ssW,$ssH, 690, 100) GUISetState(@SW_SHOW, $mainWindow) GUIRegisterMsg($WM_NOTIFY, "WM_Notify_Events") While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE _Exit() EndSwitch WEnd Func Test() For $k = 1 To UBound($aFiles) - 1 screenshotWidgetTransition($aFiles[$k]) Next EndFunc Func ListView_Click() ConsoleWrite("Left Click") EndFunc Func ListView_DoubleClick() ConsoleWrite("Double Left Click") Test() EndFunc Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam) #forceref $hWndGUI, $MsgID, $wParam Local $tagNMHDR, $event, $hwndFrom, $code $tagNMHDR = DllStructCreate("int;int;int", $lParam) If @error Then Return $event = DllStructGetData($tagNMHDR, 3) Select Case $wParam = $ListView Select Case $event = $NM_CLICK ListView_Click () Case $event = $NM_DBLCLK ListView_DoubleClick () EndSelect EndSelect Return $GUI_RUNDEFMSG EndFunc Func screenshotWidgetTransition($image, $delay = 0, $speed = 1, $sleep = 2000) Local $a, $d = $c, $iX, $iY $ssImage = _GDIPlus_ImageLoadFromFile($image) $iX = _GDIPlus_ImageGetWidth($ssImage) $iY = _GDIPlus_ImageGetHeight($ssImage) $FDesktop=$ssH/$ssW $Fact =1 If $iX > $ssW And $FDesktop > ($iY/$iX) Then $Fact=$ssW/$iX ElseIf $iY > $ssH Then $Fact=$ssH/$iY EndIf $H1 = Round(($Fact * $iY),0) $W1 = Round(($Fact * $iX),0) _GDIPlus_GraphicsDrawImageRect($ssGraphic[$d], $ssImage,($ssW - $W1)/2, ($ssH - $H1) / 2,$W1,$H1) WinSetTrans($ssGDI[$d], "", 0) WinSetOnTop($ssGDI[$d], "", 1) For $a = 0 To 254 Step $speed WinSetTrans($ssGDI[$d], "", $a) Sleep($delay) Next WinSetTrans($ssGDI[$d], "", 254) WinSetOnTop($ssGDI[Not ($d)], "", 0) WinSetTrans($ssGDI[Not ($d)], "", 0) _GDIPlus_GraphicsClear($ssGraphic[Not ($d)]) $c = 1 - $d _GDIPlus_ImageDispose ($ssImage) ; very important to realease the pics Sleep($sleep) EndFunc ;==>screenshotWidgetTransition Func screenshotWidgetInit($ssW,$ssH,$ssX,$ssY) $ssGDI[2] = GUICreate("", $ssW, $ssH, $ssX, $ssY, $WS_POPUP, $WS_EX_MDICHILD, $mainWindow) $ssGDI[0] = GUICreate("", $ssW, $ssH, 3, 3, $WS_POPUP, $WS_EX_MDICHILD, $ssGDI[2]) $ssGDI[1] = GUICreate("", $ssW, $ssH, 3, 3, $WS_POPUP, $WS_EX_MDICHILD, $ssGDI[2]) ; GUISetBkColor("0x" & $bg_color, $ssGDI[2]) GUISetState(@SW_SHOW, $ssGDI[2]) GUISetState(@SW_SHOW, $ssGDI[0]) GUISetState(@SW_SHOW, $ssGDI[1]) WinSetTrans($ssGDI[0], "", 0) WinSetTrans($ssGDI[1], "", 0) _GDIPlus_Startup() $ssGraphic[0] = _GDIPlus_GraphicsCreateFromHWND($ssGDI[0]) $ssGraphic[1] = _GDIPlus_GraphicsCreateFromHWND($ssGDI[1]) _GDIPlus_GraphicsClear($ssGraphic[0], "0xFF" & $bg_color) _GDIPlus_GraphicsClear($ssGraphic[1], "0xFF" & $bg_color) EndFunc ;==>screenshotWidgetInit Func _Exit() _GDIPlus_ImageDispose($ssImage) _GDIPlus_GraphicsDispose($ssGraphic[0]) _GDIPlus_GraphicsDispose($ssGraphic[1]) GUIDelete($ssGDI[0]) GUIDelete($ssGDI[1]) GUIDelete($ssGDI[2]) _GDIPlus_Shutdown() Exit EndFunc ;==>_Exit I hope someone can shed light on this; perhaps a different approach is needed?
      Thank you in advance!
      P.S.
      The script is patched from different scripts of different users in the forum - thank you again users!