Jump to content
Rhazz

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

Recommended Posts

Rhazz

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
Danyfirex

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
Rhazz

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
Danyfirex

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
Rhazz

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
Danyfirex

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
Rhazz

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
alien4u

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

    • FrancescoDiMuro
      By FrancescoDiMuro
      Good evening everyone
      First, I want to apologize with you for the title not very clear, but I thought a little bit on which title to set at the thread, and this is the one that came in mind.
      Now, let me explain what I'm trying to understand.

      I am making an application ( with n clients ), with an SQLite Database, which has a Main form, and n sub-forms... 
      Since these sub-forms are called several times, because they are used to add or update records to the Database, I put the code that generates the GUI of these sub-forms in Functions.
      There are two sub-forms which are "treated" as two main forms, since even them have n sub-forms, which perform various tasks.
      Where am I stucked?

      For the Main form I created a Status Bar, in order to display messages ( add/delete/update/search results ), and it works perfectly with all the forms which don't have other sub-forms.
      For the two forms, which indeed have n sub-forms, I created two separated Status Bars, which are (re)created everytime I call the function that then displays the form.
      Practically, I can't set icons to these two Status Bars, and I don't know why.
      I'm really sorry that I don't feel clear enough, so, here you are an example of what I am saying.
      I recreated exactly what my script does:
      #include <GuiButton.au3> #include <GUIConstantsEx.au3> #include <GuiStatusBar.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) Global $frmSubForm, _ $txtSubFormField, _ $sbSubFormStatusBar, _ $objSB_IconError = _WinAPI_LoadShell32Icon(109), _ $objSB_IconInformation = _WinAPI_LoadShell32Icon(277) #Region ### START Koda GUI section ### Form= $frmMainForm = GUICreate("Main Form", 300, 300, -1, -1) GUISetOnEvent($GUI_EVENT_CLOSE, "ExitApplication") $sbMainStatusBar = _GUICtrlStatusBar_Create($frmMainForm) $btnCreateSubForm = GUICtrlCreateButton("Create Sub Form", 105, 110, 75, 41, BitOR($BS_CENTER,$BS_VCENTER,$BS_MULTILINE)) GUICtrlSetOnEvent(-1, "GenerateSubForm") GUICtrlSetFont(-1, 10, 400, 0, "Arial") _GUICtrlStatusBar_SetSimple($sbMainStatusBar) _GUICtrlStatusBar_SetText($sbMainStatusBar, "") GUISetState(@SW_SHOW, $frmMainForm) #EndRegion ### END Koda GUI section ### While 1 Sleep(100) WEnd Func ExitApplication() Exit EndFunc Func GenerateSubForm() #Region ### START Koda GUI section ### Form= $frmSubForm = GUICreate("Sub-Form", 300, 300, -1, -1, -1, -1, $frmMainForm) GUISetOnEvent($GUI_EVENT_CLOSE, "DeleteSubForm") $txtSubFormField = GUICtrlCreateInput("", 0, 0, 100, 20) $btnCheckSubFormField = GUICtrlCreateButton("Check Field", 105, 110, 75, 41, BitOR($BS_CENTER,$BS_VCENTER,$BS_MULTILINE)) GUICtrlSetOnEvent(-1, "CheckSubFormField") GUICtrlSetFont(-1, 10, 400, 0, "Arial") $sbSubFormStatusBar = _GUICtrlStatusBar_Create($frmSubForm) _GUICtrlStatusBar_SetSimple($sbSubFormStatusBar) _GUICtrlStatusBar_SetText($sbSubFormStatusBar, "") GUISetState(@SW_SHOW, $frmSubForm) GUISetState(@SW_DISABLE, $frmMainForm) #EndRegion ### END Koda GUI section ### EndFunc Func DeleteSubForm() ; Declared Globally => $frmSubForm GUIDelete($frmSubForm) GUISetState(@SW_ENABLE, $frmMainForm) EndFunc Func WriteToStatusBar($sbStatusBar, $objSB_Icon, $strText) _GUICtrlStatusBar_SetIcon($sbStatusBar, 0, $objSB_Icon) _GUICtrlStatusBar_SetText($sbStatusBar, $strText) ConsoleWrite("Icon Handle: " & $objSB_Icon & @CRLF) EndFunc Func CheckSubFormField() ; Declared Globally => $txtSubFormField If GUICtrlRead($txtSubFormField) = "" Then ; Declared Globally => $sbStatusBar WriteToStatusBar($sbSubFormStatusBar, $objSB_IconError, "Field NOK.") Else WriteToStatusBar($sbSubFormStatusBar, $objSB_IconInformation, "Field OK.") EndIf EndFunc The text is set, but icon is not.
      Could someone please tell me why?
      Thanks everyone in advance  

      Best Regards.
    • Reziskonh
      By Reziskonh
      Hi, everybody
      I look for GUI whose behavior similar to the message of an email client or antivirus
      In other words:
          Any PC screen able to calculate the size
          To consider the Task bar size
          To find the lower corner on the right/below and to nestle on it

      Notes:
      In GUI the GUICtrlCreateEdit field (as option) - that can be received and displayed through variable information
      Thanks a lot
      PS
      I use the translator, excuse if something is not clear
       

    • VollachR
      By VollachR
      Hi,
      I'd like to show a progress bar for an operation performed by an external program my script is running silently, I want to show it in a GUI I created using the GUICtrlCreateProgress but I have no idea how to do it.
      The important thing to point out is that there's no way of knowing how long the external program will run, as it is a file splitter and it depends on the size of file it splits and the split parts size.
      Can someone point me in the right direction or give me an example how to do so?
      This is my RunWait command:
      RunWait($MYFILES1 & '\fsplit.exe -split ' & $Size & ' mb ' & $File & " -f " & $File & "." & $extension) It uses multiple variables declared and set earlier in the script, how will I got about having the progress of that command shown using GUICtrlCreateProgress ? Is it possible?
      Thank you.
    • nacerbaaziz
      By nacerbaaziz
      Hello my friends
      I have an inquiry and I hope to find the answer here
      I want to create a graphical user interface
      but I want to hide the system menu
      I mean the window menu
      Is this possible?
      If is possible please give me how to do that
      Thanks in advance
×