找回密码
 加入
搜索
查看: 13221|回复: 29

[效率算法] 讨论下在GUI里,循环执行某些代码时,无法暂停关闭的解决方案[已解决]

 火... [复制链接]
发表于 2011-6-23 23:36:26 | 显示全部楼层 |阅读模式
本帖最后由 xwt620 于 2011-6-30 21:47 编辑

曾今写过一些自动安装的GUI,里面有一个【开始安装】按钮,在执行自动安装时,如果判断某个窗口TITLE未出现时,或长时间不出现,这时想点击GUI里面的暂停按钮,或者关闭按钮都是无效的,当时的解决方案是设定一个超时时间返回@error,来强行停止软件,或者设置一个HOTKEY关闭软件来解决。
如今写了一些程序在执行FOR语句或者是WHILE,do...until等循环语句时,只要没有执行完,点击GUI里面的按钮还有关闭都是没有反映的,或者说是无效
所以提出这个问题希望大家能一起讨论下算法,怎样才能实现点击GUI里面按钮能让程序暂停或关闭。
补充一下
我在论坛也搜索过相关帖子,但那些都是操作时间或者数字相关的“开始”“暂停”,而对于filecopy()等函数如果文件太大,一时间又没有完成函数,那么这时点击按钮是没有效果的,还有写自动安装也一样,如果WinWaitActive一直等不到窗口出现,那么程序就一直处于假死状态,点击GUI里的按钮是没反应的。
发表于 2011-6-24 00:45:53 | 显示全部楼层
楼主在提问之前怎么不搜索下论坛,此类问题,论坛已经有N多相关帖子了...
事件模式可以很好的解决这类问题....


While
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 236, 254, 519, 138)
GUISetOnEvent($GUI_EVENT_CLOSE, "Quit")
$Label1 = GUICtrlCreateLabel("0", 112, 72, 10, 17)
$Button1 = GUICtrlCreateButton("开始", 80, 136, 75, 25)
GUICtrlSetOnEvent($Button1, "stat")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

Global $i=0,$stat = False
While 1
        If $stat = True Then
                $i+=1
            GUICtrlSetData ($Label1,$i)
    EndIf
        Sleep(100)
WEnd

Func stat()
         If $stat = True Then
                $stat = False
                GUICtrlSetData ($Button1,"开始")
        Else
                $stat = True
                GUICtrlSetData ($Button1,"暂停")
        Endif
EndFunc

Func Quit()
        Exit
EndFunc
While内带For
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 236, 254, 519, 138)
GUISetOnEvent($GUI_EVENT_CLOSE, "Quit")
$Label1 = GUICtrlCreateLabel("0", 112, 72, 10, 17)
$Button1 = GUICtrlCreateButton("开始", 80, 136, 75, 25)
GUICtrlSetOnEvent($Button1, "stat")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

Global $stat = False
While 1
For $i=1 To 10000
        If $stat = True Then
        GUICtrlSetData ($Label1,$i)
    EndIf
        Sleep(100)
Next
WEnd

Func stat()
         If $stat = True Then
                $stat = False
                GUICtrlSetData ($Button1,"开始")
        Else
                $stat = True
                GUICtrlSetData ($Button1,"暂停")
        Endif
EndFunc

Func Quit()
        Exit
EndFunc
发表于 2011-6-24 09:06:33 | 显示全部楼层
这个问题已经讨论了很久了。
发表于 2011-6-24 12:50:00 | 显示全部楼层
2楼的回复确实很有参考价值,如果对于对象操作,也能如此有效那就更好了。有时有些对象的操作,失效。
 楼主| 发表于 2011-6-24 22:38:31 | 显示全部楼层
可能是我的问题没有描述清楚,我在论坛也搜索过相关帖子,但是那些都是操作时间或者数字相关的“开始”“暂停”,而对于例如filecopy()等函数如果文件太大,一时间又没有完成函数,那么这时点击按钮是没有效果的,就如我以前写的自动安装一样,如果WinWaitActive一直等不到窗口出现,那么程序就一直处于假死状态。
发表于 2011-6-25 19:33:15 | 显示全部楼层
贴出源码来看看!你这样子有谁愿意来解答!
 楼主| 发表于 2011-6-25 22:20:06 | 显示全部楼层
回复 6# hzxymkb


   可以参考我之前提出问题的帖子http://www.autoitx.com/thread-11175-1-1.html这个就是安装出错后,程序一直停留在WinWaitActive上,此时点击gui上按钮时,程序是没有任何反应的。
还有一个问题是我写的批量文件复制出现的问题,就是有些文件太大了,在复制过程中想点击“取消”按钮也不能取消,这个程序里用的就是filecopy()。
其实这两个问题是相似的,我理解的就是filecopy()WinWaitActive()占用了程序的线程,而不能回应其他按钮事件。
所以就需要一种方案能够解决这种问题。
 楼主| 发表于 2011-6-25 22:44:27 | 显示全部楼层
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

$i = 0
Opt("GUIOnEventMode", 1)
$Form1_1 = GUICreate("文件复制器", 292, 150, @DesktopWidth / 3, @DesktopHeight / 3)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

$Label1 = GUICtrlCreateLabel("文件类型 :", 8, 8, 58, 17)
$Combo1 = GUICtrlCreateCombo("所有类型", 72, 8, 73, 25)
$Button1 = GUICtrlCreateButton("设置", 160, 8, 51, 25, $WS_GROUP)
GUICtrlSetOnEvent(-1, "add_style")

$Label2 = GUICtrlCreateLabel("文件路径 :", 8, 40, 58, 17)
$Input2 = GUICtrlCreateInput("文件路径", 72, 40, 153, 21)
$Button2 = GUICtrlCreateButton("浏览", 232, 40, 51, 25, $WS_GROUP)
GUICtrlSetOnEvent(-1, "on_event")

$Label3 = GUICtrlCreateLabel("保存路径 :", 8, 72, 58, 17)
$Input3 = GUICtrlCreateInput("保存路径", 72, 72, 153, 21)
$Button3 = GUICtrlCreateButton("浏览", 232, 72, 51, 25, $WS_GROUP)
GUICtrlSetOnEvent(-1, "on_event")

$Label4 = GUICtrlCreateLabel("文件名称 :", 8, 104, 58, 17)
$Input4 = GUICtrlCreateInput("文件名", 72, 104, 153, 21)

$Button5 = GUICtrlCreateButton("复制", 232, 104, 51, 25, $WS_GROUP)
GUICtrlSetOnEvent(-1, "on_event")
GUISetState(@SW_SHOW)

start()
While 1
        Sleep(1000)
WEnd

Func add_style()
        MsgBox(0, '消息', '抱歉,暂无此功能!')
EndFunc   ;==>add_style

Func on_event()
        Switch @GUI_CtrlId
                Case $Button2
                        $f_sytle = GUICtrlRead($Combo1)
                        $f_folder = GUICtrlRead($Input2)
                        If $f_sytle = "所有类型" Then $f_sytle = ".*"
                        If $f_sytle <> "" And StringLeft($f_sytle, 1) = "." Then
                                $SF2 = FileSelectFolder("选择文件夹", "", 4 + 2, $f_folder)
                                If $SF2 <> "" Then
                                        If StringRight($SF2, 1) <> "" Then $SF2 = $SF2 & "" ;读取最右边的字符然后加 “\”
                                        GUICtrlSetData($Input2, $SF2, "")
                                        $search = FileFindFirstFile($SF2 & '*' & $f_sytle)
                                        If $search = -1 Then
                                                MsgBox(0, "错误", "文件夹中没有后缀为" & $f_sytle & "文件", 5)
                                                GUICtrlSetData($Input2, "文件路径", "")
                                        EndIf
                                EndIf
                        Else
                                MsgBox(64, "错误", "没有选择类型或输入错误", 5)
                        EndIf

                Case $Button3
                        $f_folder = GUICtrlRead($Input2)
                        $SF3 = FileSelectFolder("选择文件夹", "", 4 + 2, $f_folder)
                        If $SF3 <> "我的电脑" And $SF3 <> "网上邻居" And $SF3 <> "回收站" And $SF3 <> "" Then
                                If StringRight($SF3, 1) <> "" Then $SF3 = $SF3 & ""
                                GUICtrlSetData($Input3, $SF3, "")
                        EndIf

                Case $Button5
                        $f_sytle = GUICtrlRead($Combo1)
                        $f_folder = GUICtrlRead($Input2)
                        $s_folder = GUICtrlRead($Input3)
                        $filename = GUICtrlRead($Input4)

                        If $f_folder <> "" And $f_folder <> "文件路径" And $s_folder <> "" And $s_folder <> "保存路径" Then
                                If $filename = "" Then
                                        MsgBox(0, '错误', '没有指定文件名')
                                Else
                                        If $f_sytle = "所有类型" Then $f_sytle = ".*"
                                        $search = FileFindFirstFile($f_folder & "*" & $f_sytle)
                                        If $search <> -1 Then
                                                While 1
                                                        $file = FileFindNextFile($search)
                                                        If @error Then ExitLoop
                                                        $files = StringInStr($file, $filename)
                                                        If $files <> 0 Then ;检查是否包含文件名的文件
                                                                FileCopy($f_folder & $file, $s_folder, 1)
                                                                $i += 1
                                                        EndIf
                                                WEnd
                                                If $i <> 0 Then
                                                        MsgBox(64, '结果', '成功复制包含文件名为 [' & $filename & '] 共 ' & $i & ' 个文件', 3)
                                                Else
                                                        MsgBox(64, '结果', '文件夹中没有包含文件名为 [' & $filename & ']的文件', 3)
                                                EndIf
                                                $i = 0
                                        EndIf
                                EndIf
                        Else
                                MsgBox(64, "错误", "没有选择路径", 5)
                        EndIf
        EndSwitch
EndFunc   ;==>on_event

Func start()
        GUICtrlSetData($Combo1, ".jpg")
        GUICtrlSetData($Combo1, ".gif")
        GUICtrlSetData($Combo1, ".txt")
        GUICtrlSetData($Combo1, ".mp3")
        GUICtrlSetData($Combo1, ".wma")
        GUICtrlSetData($Combo1, ".rm")
        GUICtrlSetData($Combo1, ".bmp")
        GUICtrlSetData($Combo1, ".au3")
        GUICtrlSetData($Combo1, ".exe")
        GUICtrlSetData($Combo1, ".ico")
EndFunc   ;==>start

Func _Exit()
        $iAnswer = MsgBox(4 + 256 + 32, "确认", "退出吗?")
        Select
                Case $iAnswer = 6 ;OK
                        Exit 0
                Case $iAnswer = 7 ;Cancel

        EndSelect
EndFunc   ;==>_Exit
写这个是因为公司里有些文件夹里的文件很多,用我的电脑打开会很慢,但是每个文件都有关键字存在,用这个程序复制出来就很方便了,但是复制时,点击程序中的关闭按钮就没有反应。
我另一个版本比这个写的更好的源码我放哪去了
发表于 2011-6-25 22:48:19 | 显示全部楼层
写这个是因为公司里有些文件夹里的文件很多,用我的电脑打开会很慢,但是每个文件都有关键字存在,用这个程 ...
xwt620 发表于 2011-6-25 22:44



    天,不会吧,你这样搞,效率太低了
你需要的一个文件管理器软件,如TotalCommander,Dopus之类的。
 楼主| 发表于 2011-6-25 22:58:14 | 显示全部楼层
天,不会吧,你这样搞,效率太低了
你需要的一个文件管理器软件,如TotalCommander,Dopus之类的 ...
happytc 发表于 2011-6-25 22:48



   我那里没有外网,有时候就需要自己写些简单而且实用的小程序来方便自己。
而且重在学习,我提出这个问题,也是想让自己能掌握更多编程方法。
发表于 2011-6-25 22:59:53 | 显示全部楼层
回复 10# xwt620


    我说的是用软件,跟有没有外网有啥关系呀?

当然,若仅仅是练手写code就另说。
 楼主| 发表于 2011-6-25 23:36:43 | 显示全部楼层
回复 11# happytc


  呵呵, 我现在不仅仅是练手,也是想解决程序中的BUG,对于我提出的问题,刚刚有个搞开发的师傅跟我说,要我用多线程来解决,他的解释是我所用的函数将我的主线程的资源全部占用了,如果这个函数没有结束,此时就会出现我所说的情况,需要用主线程对副线程进行控制,这样就可以解决我的问题。
今天算是又学了一招,但是还需要花点时间去研究下多线程。
发表于 2011-6-25 23:44:50 | 显示全部楼层
回复 12# xwt620


    前面不是有人已经跟你说了,若用au3的话,别用消息模式,用事件模式就可以解决了。au3不支持多线程
 楼主| 发表于 2011-6-25 23:48:36 | 显示全部楼层
回复 13# happytc


    我的程序都是用的事件模式啊,而且我也很喜欢使用事件模式。
 楼主| 发表于 2011-6-25 23:54:34 | 显示全部楼层
回复  xwt620


    au3不支持多线程happytc 发表于 2011-6-25 23:44



    搜索了下,好像支持还是可以支持,只是目前没有直接可用的多线程函数,而是需要用其他DLLCALL之类的函数调用吧,只是感觉很有点麻烦,至少对于我(新手)来说---就是不会用。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-12 23:36 , Processed in 0.084072 second(s), 23 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表