Что нового

Формирование GUI теста по txt

SergVrn

Новичок
Сообщения
87
Репутация
2
Доброго времени суток, форумчане.

Подскажите как реализовать такой скрипт с интерфейсом GUI:

В текстовом документе содержатся вопросы теста. Вопросов несколько и они идут - один за другим.

Как скриптом сформировать по этому txt - интерфейс теста с кнопками ?
Если ответ правильный (правильный щелчок на нужную кнопку выбора ответа теста) - то GUI скрывается в трей и появляется через 10-20 минут (если ответ неверный - то окно ничего не делает, никуда не исчезает, а через 1 минуту повторяет случайный вопрос)
 

Вложения

  • Тестовые вопросы и ответы.txt
    350 байт · Просмотры: 11

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
SergVrn [?]
Подскажите как реализовать такой скрипт с интерфейсом GUI:
Ну это не подсказка тут нужна, а реализация задачи.

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $sRead = FileRead('Тестовые вопросы и ответы.txt')
Global $aData = StringRegExp($sRead, '(?s)(Вопрос \d+\r?\n[^\r\n]+\r?\nОтветы:\r?\n.*?\r?\nПравильный:\r?\n[^\r\n]+)', 3)
Global $aQuestion_Bttn[10], $iQuestion_Lbl, $sCorret_Answer

Opt('TrayMenuMode', 1)
TraySetState(2)

$hGUI = GUICreate('Test')

_Random_Question()

GUISetState(@SW_SHOW)

While 1
	$nMsg = GUIGetMsg()
	
	Switch $nMsg
		Case 0
			ContinueLoop
		Case $GUI_EVENT_CLOSE
			Exit
		Case $aQuestion_Bttn[1] To $aQuestion_Bttn[9]
			If GUICtrlRead($nMsg) = $sCorret_Answer Then
				TraySetState(1)
				GUISetState(@SW_HIDE)
				Sleep(1000 * 60 * 10) ;10 minutes
				GUISetState(@SW_SHOW)
				TraySetState(2)
				
				_Random_Question()
			Else
				Sleep(1000 * 60 * 1) ;1 minute
				_Random_Question()
			EndIf
	EndSwitch
WEnd

Func _Random_Question()
	Local Static $fFirst = True
	Local Static $iLast_Random
	
	Local $iRandom
	
	Do
		$iRandom = Random(0, UBound($aData) - 1, 1)
	Until $iRandom <> $iLast_Random
	
	$iLast_Random = $iRandom
	
	Local $sQuestion = StringRegExpReplace($aData[$iRandom], '(?s)Вопрос \d+\r?\n([^\r\n]+).*', '\1')
	Local $aQuestions = StringSplit(StringStripCR(StringRegExpReplace($aData[$iRandom], '(?s).*?Ответы:\r?\n(.*?)\r?\nПравильный:.*', '\1')), @LF)
	
	$sCorret_Answer = StringRegExpReplace($aData[$iRandom], '(?s).*?\r?\nПравильный:\r?\n([^\r\n]+)', '\1')
	
	If $fFirst Then
		$fFirst = False
		$iQuestion_Lbl = GUICtrlCreateLabel('', 20, 20, 200, 20)
		
		For $i = 1 To 9
			$aQuestion_Bttn[$i] = GUICtrlCreateButton('', 20, $i * 40, 200, 20)
			GUICtrlSetState($aQuestion_Bttn[$i], $GUI_HIDE)
		Next
	EndIf
	
	GUICtrlSetData($iQuestion_Lbl, $sQuestion)
	
	For $i = 1 To 9
		GUICtrlSetData($aQuestion_Bttn[$i], '')
		GUICtrlSetState($aQuestion_Bttn[$i], $GUI_HIDE)
	Next
	
	For $i = 1 To $aQuestions[0]
		GUICtrlSetData($aQuestion_Bttn[$i], $aQuestions[$i])
		GUICtrlSetState($aQuestion_Bttn[$i], $GUI_SHOW)
	Next
EndFunc
 
Автор
S

SergVrn

Новичок
Сообщения
87
Репутация
2
CreatoR спасибо.
Все работает хорошо.
Но немного неточно.

Есть возможность сразу при первом запуске окна - нажать несколько неверных ответов.

Как поменять скрипт, чтобы он при неверном ответе - просто убирал бы кнопки с формы - на 1 минуту (пока длится пауза) ?
А потом бы, спустя минуту - снова показывал их при задании нового вопроса.
Таким образом нельзя будет нажать на кнопки несколько раз - только один раз - на одну кнопку.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
SergVrn [?]
немного неточно.
А вопрос был точно составлен? мне кажется нет, там нет упоминания о таких нюансах.

Как поменять скрипт, чтобы он при неверном ответе - просто убирал бы кнопки с формы - на 1 минуту (пока длится пауза) ?
Я бы их просто отключал.
Предвкушая вопрос о том, чтобы добавить отображение статуса...
"Исправленный" вариант:

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

FileChangeDir(@DesktopDir)

Global $sRead = FileRead('Тестовые вопросы и ответы.txt')
Global $aData = StringRegExp($sRead, '(?s)(Вопрос \d+\r?\n[^\r\n]+\r?\nОтветы:\r?\n.*?\r?\nПравильный:\r?\n[^\r\n]+)', 3)
Global $aQuestion_Bttn[10], $iQuestion_Lbl, $sCorret_Answer
Global $iTimer

Global $iCrctAnswr_Sleep = 10 ;Minutes
Global $iInCrctAnswr_Sleep = 1 ;Minutes

Opt('TrayMenuMode', 1)
TraySetState(2)

$hGUI = GUICreate('Questions', 250, 300)

$iStatus_Lbl = GUICtrlCreateLabel('', 20, 270, 210, 30)
GUICtrlSetColor(-1, 0xFF0000)

_Questions_SetRandom()

GUISetState(@SW_SHOW)

While 1
	$nMsg = GUIGetMsg()
	
	Switch $nMsg
		Case 0
			ContinueLoop
		Case $GUI_EVENT_CLOSE
			Exit
		Case $aQuestion_Bttn[1] To $aQuestion_Bttn[9]
			If GUICtrlRead($nMsg) = $sCorret_Answer Then
				TraySetState(1)
				GUISetState(@SW_HIDE)
				Sleep(1000 * 60 * $iCrctAnswr_Sleep)
				GUISetState(@SW_SHOW)
				TraySetState(2)
			Else
				$iTimer = TimerInit()
				AdlibRegister('_Status_Timer', 1000)
				_Status_Timer()
				
				_Questions_SetState($GUI_DISABLE)
				Sleep(1000 * 60 * $iInCrctAnswr_Sleep)
				_Questions_SetState($GUI_ENABLE)
				
				AdlibUnRegister('_Status_Timer')
				GUICtrlSetData($iStatus_Lbl, '')
			EndIf
			
			_Questions_SetRandom()
	EndSwitch
WEnd

Func _Status_SetData($sData)
	If GUICtrlRead($iStatus_Lbl) <> $sData Then
		GUICtrlSetData($iStatus_Lbl, $sData)
	EndIf
EndFunc

Func _Status_Timer()
	_Status_SetData('Неверный ответ, до нового вопроса осталось: ' & (($iInCrctAnswr_Sleep * 60) - Round(TimerDiff($iTimer) / 1000)) & ' сек.')
EndFunc

Func _Questions_SetRandom()
	Local Static $fFirst = True
	Local Static $iLast_Random
	
	Local $iRandom
	
	Do
		$iRandom = Random(0, UBound($aData) - 1, 1)
	Until $iRandom <> $iLast_Random
	
	$iLast_Random = $iRandom
	
	Local $sQuestion = StringRegExpReplace($aData[$iRandom], '(?s)Вопрос \d+\r?\n([^\r\n]+).*', '\1')
	Local $aQuestions = StringSplit(StringStripCR(StringRegExpReplace($aData[$iRandom], '(?s).*?Ответы:\r?\n(.*?)\r?\nПравильный:.*', '\1')), @LF)
	
	$sCorret_Answer = StringRegExpReplace($aData[$iRandom], '(?s).*?\r?\nПравильный:\r?\n([^\r\n]+)', '\1')
	
	If $fFirst Then
		$fFirst = False
		$iQuestion_Lbl = GUICtrlCreateLabel('', 20, 20, 200, 20)
		
		For $i = 1 To 9
			$aQuestion_Bttn[$i] = GUICtrlCreateButton('', 20, $i * 40, 200, 20)
			GUICtrlSetState($aQuestion_Bttn[$i], $GUI_HIDE)
		Next
	EndIf
	
	GUICtrlSetData($iQuestion_Lbl, $sQuestion)
	
	For $i = 1 To 9
		GUICtrlSetData($aQuestion_Bttn[$i], '')
		GUICtrlSetState($aQuestion_Bttn[$i], $GUI_HIDE)
	Next
	
	For $i = 1 To $aQuestions[0]
		GUICtrlSetData($aQuestion_Bttn[$i], $aQuestions[$i])
		GUICtrlSetState($aQuestion_Bttn[$i], $GUI_SHOW)
	Next
EndFunc

Func _Questions_SetState($iState)
	For $i = 1 To 9
		If $aQuestion_Bttn[$i] Then
			GUICtrlSetState($aQuestion_Bttn[$i], $iState)
		EndIf
	Next
EndFunc
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Хотя я бы делал лучше так:

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $sData_File = @ScriptDir & '\Data.ini'
Global $aQuestion_Bttn[10], $sCorret_Answer, $iTimer
Global $iCrctAnswr_Sleep = 10 ;Minutes
Global $iInCrctAnswr_Sleep = 1 ;Minutes

Opt('TrayMenuMode', 1)
TraySetState(2)

Global $hGUI = GUICreate('Questions', 250, 300)
Global $iStatus_Lbl = GUICtrlCreateLabel('', 20, 270, 210, 30)
GUICtrlSetColor(-1, 0xFF0000)

_Questions_SetRandom()
GUISetState(@SW_SHOW)

While 1
	$nMsg = GUIGetMsg()
	
	Switch $nMsg
		Case 0
			ContinueLoop
		Case $GUI_EVENT_CLOSE
			Exit
		Case $aQuestion_Bttn[1] To $aQuestion_Bttn[9]
			If GUICtrlRead($nMsg) = $sCorret_Answer Then
				TraySetState(1)
				GUISetState(@SW_HIDE)
				Sleep(1000 * 60 * $iCrctAnswr_Sleep)
				GUISetState(@SW_SHOW)
				TraySetState(2)
			Else
				$iTimer = TimerInit()
				AdlibRegister('_Status_Timer', 1000)
				_Status_Timer()
				
				_Questions_SetState($GUI_DISABLE)
				Sleep(1000 * 60 * $iInCrctAnswr_Sleep)
				_Questions_SetState($GUI_ENABLE)
				
				AdlibUnRegister('_Status_Timer')
				GUICtrlSetData($iStatus_Lbl, '')
			EndIf
			
			_Questions_SetRandom()
	EndSwitch
WEnd

Func _Status_Timer()
	_Status_SetData('Неверный ответ, до нового вопроса осталось: ' & (($iInCrctAnswr_Sleep * 60) - Round(TimerDiff($iTimer) / 1000)) & ' сек.')
EndFunc

Func _Status_SetData($sData)
	If GUICtrlRead($iStatus_Lbl) <> $sData Then
		GUICtrlSetData($iStatus_Lbl, $sData)
	EndIf
EndFunc

Func _Questions_SetRandom()
	Local Static $fFirst = True
	Local Static $iLast_Random, $iQuestion_Lbl
	
	Local $iRandom
	Local $aSects = IniReadSectionNames($sData_File)
	
	If Not IsArray($aSects) Then
		MsgBox(48, @ScriptName, 'Ошибка чтения вопросов с файла:' & @CRLF & $sData_File, 0, $hGUI)
		Exit
	EndIf
	
	Do
		$iRandom = Random(1, $aSects[0], 1)
	Until $iRandom <> $iLast_Random
	
	$iLast_Random = $iRandom
	
	Local $sQuestion = IniRead($sData_File, $aSects[$iRandom], 'Question', '')
	Local $aAnswers = StringSplit(IniRead($sData_File, $aSects[$iRandom], 'Answers', ''), '|')
	
	$sCorret_Answer = IniRead($sData_File, $aSects[$iRandom], 'Correct Answer', '')
	
	If $fFirst Then
		$fFirst = False
		$iQuestion_Lbl = GUICtrlCreateLabel('', 20, 20, 200, 20)
		
		For $i = 1 To 9
			$aQuestion_Bttn[$i] = GUICtrlCreateButton('', 20, $i * 40, 200, 20)
			GUICtrlSetState($aQuestion_Bttn[$i], $GUI_HIDE)
		Next
	EndIf
	
	GUICtrlSetData($iQuestion_Lbl, $sQuestion)
	
	For $i = 1 To 9
		GUICtrlSetData($aQuestion_Bttn[$i], '')
		GUICtrlSetState($aQuestion_Bttn[$i], $GUI_HIDE)
	Next
	
	For $i = 1 To $aAnswers[0]
		GUICtrlSetData($aQuestion_Bttn[$i], $aAnswers[$i])
		GUICtrlSetState($aQuestion_Bttn[$i], $GUI_SHOW)
	Next
EndFunc

Func _Questions_SetState($iState)
	For $i = 1 To 9
		If $aQuestion_Bttn[$i] Then
			GUICtrlSetState($aQuestion_Bttn[$i], $iState)
		EndIf
	Next
EndFunc


Файл Data.ini:
INI:
[Q1]
Question=Сколько длятся сутки?
Answers=23 часа|20 часов|25 часов|24 часа|Ни один из ответов
Correct Answer=24 часа

[Q2]
Question=Сколько минут в часе?
Answers=50 минут|60 минут|40 минут|Ни один из ответов
Correct Answer=60 минут
 
Автор
S

SergVrn

Новичок
Сообщения
87
Репутация
2
CreatoR
Подскажите, а если одна из записей в тексте файла txt - будет выглядеть так:

Код:
Вопрос 3
Сколько времени показано на картинке?
Адрес:
C:\папка с картинками\
Ответы:
1 час 50 минут
7 часов 15 минут
12 часов 10 минут
Ни один из ответов
Правильный:
7 часов 15 минут


Как разместить на этой форме - под последней кнопкой ответа - уменьшенную копию картинки, лежащей по данному адресу ?
 

Вложения

  • Тестовые вопросы и ответы.txt
    542 байт · Просмотры: 5

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
SergVrn [?]
если одна из записей в тексте файла txt - будет выглядеть так
Кто устанавливает структуру этого файла?
Если файл твой, то я показал выше как это делать проще и доступнее.

Вариант №1 для картинки (исходная структура файла - не рекомендуемая)
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $sRead = FileRead(@ScriptDir & '\Тестовые вопросы и ответы.txt')
Global $aData = StringRegExp($sRead, '(?s)(Вопрос \d+\r?\n[^\r\n]+\r?\n(?:Адрес:\r?\n[^\r\n]+\r?\n)?Ответы:\r?\n.*?\r?\nПравильный:\r?\n[^\r\n]+)', 3)
Global $aQuestion_Bttn[10], $iQuestion_Lbl, $iImage_Pic, $sCorret_Answer
Global $iTimer

Global $iCrctAnswr_Sleep = 10 ;Minutes
Global $iInCrctAnswr_Sleep = 1 ;Minutes

Opt('TrayMenuMode', 1)
TraySetState(2)

$hGUI = GUICreate('Questions', 250, 400)

$iStatus_Lbl = GUICtrlCreateLabel('', 20, 370, 210, 30)
GUICtrlSetColor(-1, 0xFF0000)

_Questions_SetRandom()

GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    
    Switch $nMsg
        Case 0
            ContinueLoop
        Case $GUI_EVENT_CLOSE
            Exit
        Case $aQuestion_Bttn[1] To $aQuestion_Bttn[9]
            If GUICtrlRead($nMsg) = $sCorret_Answer Then
                TraySetState(1)
                GUISetState(@SW_HIDE)
                Sleep(1000 * 60 * $iCrctAnswr_Sleep)
                GUISetState(@SW_SHOW)
                TraySetState(2)
            Else
                $iTimer = TimerInit()
                AdlibRegister('_Status_Timer', 1000)
                _Status_Timer()
                
                _Questions_SetState($GUI_DISABLE)
                Sleep(1000 * 60 * $iInCrctAnswr_Sleep)
                _Questions_SetState($GUI_ENABLE)
                
                AdlibUnRegister('_Status_Timer')
                GUICtrlSetData($iStatus_Lbl, '')
            EndIf
            
            _Questions_SetRandom()
    EndSwitch
WEnd

Func _Status_SetData($sData)
    If GUICtrlRead($iStatus_Lbl) <> $sData Then
        GUICtrlSetData($iStatus_Lbl, $sData)
    EndIf
EndFunc

Func _Status_Timer()
    _Status_SetData('Неверный ответ, до нового вопроса осталось: ' & (($iInCrctAnswr_Sleep * 60) - Round(TimerDiff($iTimer) / 1000)) & ' сек.')
EndFunc

Func _Questions_SetRandom()
    Local Static $fFirst = True
    Local Static $iLast_Random
    
    Local $iRandom
    
    Do
        $iRandom = Random(0, UBound($aData) - 1, 1)
    Until $iRandom <> $iLast_Random
    
    $iLast_Random = $iRandom
    
    Local $sQuestion = StringRegExpReplace($aData[$iRandom], '(?s)Вопрос \d+\r?\n([^\r\n]+).*', '\1')
    Local $aQuestions = StringSplit(StringStripCR(StringRegExpReplace($aData[$iRandom], '(?s).*?Ответы:\r?\n(.*?)\r?\nПравильный:.*', '\1')), @LF)
    Local $aAddress = StringRegExp($aData[$iRandom], '(?s).*?Адрес:\r?\n([^\r\n]+)\r\n?Ответы:.*', 3)
    
    $sCorret_Answer = StringRegExpReplace($aData[$iRandom], '(?s).*?\r?\nПравильный:\r?\n([^\r\n]+)', '\1')
    
    If $fFirst Then
        $fFirst = False
        $iQuestion_Lbl = GUICtrlCreateLabel('', 20, 20, 200, 25)
        
        For $i = 1 To 9
            $aQuestion_Bttn[$i] = GUICtrlCreateButton('', 20, $i * 45, 200, 20)
            GUICtrlSetState($aQuestion_Bttn[$i], $GUI_HIDE)
        Next
		
		$iImage_Pic = GUICtrlCreatePic('', 85, 290, 75, 75)
    EndIf
    
    GUICtrlSetData($iQuestion_Lbl, $sQuestion)
    
    For $i = 1 To 9
        GUICtrlSetData($aQuestion_Bttn[$i], '')
        GUICtrlSetState($aQuestion_Bttn[$i], $GUI_HIDE)
    Next
    
    For $i = 1 To $aQuestions[0]
        GUICtrlSetData($aQuestion_Bttn[$i], $aQuestions[$i])
        GUICtrlSetState($aQuestion_Bttn[$i], $GUI_SHOW)
    Next
	
	If IsArray($aAddress) Then
		GUICtrlSetState($iImage_Pic, $GUI_SHOW)
		GUICtrlSetImage($iImage_Pic, $aAddress[0])
	Else
		GUICtrlSetState($iImage_Pic, $GUI_HIDE)
	EndIf
EndFunc

Func _Questions_SetState($iState)
    For $i = 1 To 9
        If $aQuestion_Bttn[$i] Then
            GUICtrlSetState($aQuestion_Bttn[$i], $iState)
        EndIf
    Next
EndFunc


Вариант №2 для картинки (собственная структура ini-файла)
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $sData_File = @ScriptDir & '\Data.ini'
Global $aQuestion_Bttn[10], $sCorret_Answer, $iTimer
Global $iCrctAnswr_Sleep = 10 ;Minutes
Global $iInCrctAnswr_Sleep = 1 ;Minutes

Opt('TrayMenuMode', 1)
TraySetState(2)

Global $hGUI = GUICreate('Questions', 250, 400)
Global $iStatus_Lbl = GUICtrlCreateLabel('', 20, 370, 210, 30)
GUICtrlSetColor(-1, 0xFF0000)

_Questions_SetRandom()
GUISetState(@SW_SHOW)

While 1
	$nMsg = GUIGetMsg()
	
	Switch $nMsg
		Case 0
			ContinueLoop
		Case $GUI_EVENT_CLOSE
			Exit
		Case $aQuestion_Bttn[1] To $aQuestion_Bttn[9]
			If GUICtrlRead($nMsg) = $sCorret_Answer Then
				TraySetState(1)
				GUISetState(@SW_HIDE)
				Sleep(1000 * 60 * $iCrctAnswr_Sleep)
				GUISetState(@SW_SHOW)
				TraySetState(2)
			Else
				$iTimer = TimerInit()
				AdlibRegister('_Status_Timer', 1000)
				_Status_Timer()
				
				_Questions_SetState($GUI_DISABLE)
				Sleep(1000 * 60 * $iInCrctAnswr_Sleep)
				_Questions_SetState($GUI_ENABLE)
				
				AdlibUnRegister('_Status_Timer')
				GUICtrlSetData($iStatus_Lbl, '')
			EndIf
			
			_Questions_SetRandom()
	EndSwitch
WEnd

Func _Status_Timer()
	_Status_SetData('Неверный ответ, до нового вопроса осталось: ' & (($iInCrctAnswr_Sleep * 60) - Round(TimerDiff($iTimer) / 1000)) & ' сек.')
EndFunc

Func _Status_SetData($sData)
	If GUICtrlRead($iStatus_Lbl) <> $sData Then
		GUICtrlSetData($iStatus_Lbl, $sData)
	EndIf
EndFunc

Func _Questions_SetRandom()
	Local Static $fFirst = True
	Local Static $iLast_Random, $iQuestion_Lbl, $iImage_Pic
	
	Local $iRandom
	Local $aSects = IniReadSectionNames($sData_File)
	
	If Not IsArray($aSects) Then
		MsgBox(48, @ScriptName, 'Ошибка чтения вопросов с файла:' & @CRLF & $sData_File, 0, $hGUI)
		Exit
	EndIf
	
	Do
		$iRandom = Random(1, $aSects[0], 1)
	Until $iRandom <> $iLast_Random
	
	$iLast_Random = $iRandom
	
	Local $sQuestion = IniRead($sData_File, $aSects[$iRandom], 'Question', '')
	Local $aAnswers = StringSplit(IniRead($sData_File, $aSects[$iRandom], 'Answers', ''), '|')
	Local $sImage = IniRead($sData_File, $aSects[$iRandom], 'Image', '')
	
	$sCorret_Answer = IniRead($sData_File, $aSects[$iRandom], 'Correct Answer', '')
	
	If $fFirst Then
		$fFirst = False
		$iQuestion_Lbl = GUICtrlCreateLabel('', 20, 20, 200, 25)
		$iImage_Pic = GUICtrlCreatePic('', 85, 290, 75, 75)
		
		Local $iTop = 50
		
		For $i = 1 To 9
			$aQuestion_Bttn[$i] = GUICtrlCreateButton('', 20, $iTop, 200, 20)
			GUICtrlSetState($aQuestion_Bttn[$i], $GUI_HIDE)
			
			$iTop += 25
		Next
	EndIf
	
	GUICtrlSetData($iQuestion_Lbl, $sQuestion)
	
	For $i = 1 To 9
		GUICtrlSetData($aQuestion_Bttn[$i], '')
		GUICtrlSetState($aQuestion_Bttn[$i], $GUI_HIDE)
	Next
	
	For $i = 1 To $aAnswers[0]
		GUICtrlSetData($aQuestion_Bttn[$i], $aAnswers[$i])
		GUICtrlSetState($aQuestion_Bttn[$i], $GUI_SHOW)
	Next
	
	If $sImage Then
		GUICtrlSetState($iImage_Pic, $GUI_SHOW)
		GUICtrlSetImage($iImage_Pic, $sImage)
	Else
		GUICtrlSetState($iImage_Pic, $GUI_HIDE)
	EndIf
EndFunc

Func _Questions_SetState($iState)
	For $i = 1 To 9
		If $aQuestion_Bttn[$i] Then
			GUICtrlSetState($aQuestion_Bttn[$i], $iState)
		EndIf
	Next
EndFunc


Data.ini:
INI:
[Q1]
Question=Сколько длятся сутки?
Answers=23 часа|20 часов|25 часов|24 часа|Ни один из ответов
Correct Answer=24 часа

[Q2]
Question=Сколько минут в часе?
Answers=50 минут|60 минут|40 минут|Ни один из ответов
Correct Answer=60 минут

[Q3]
Question=Сколько времени показано на картинке?
Image=C:\Image.jpg
Answers=1 час 50 минут|7 часов 15 минут|12 часов 10 минут|Ни один из ответов
Correct Answer=7 часов 15 минут
 
Автор
S

SergVrn

Новичок
Сообщения
87
Репутация
2
CreatoR
Спасибо большое.
Первый вариант хорошо работает.
(ini не подходит, поскольку тяжело туда записывать что либо, если ответы - не короткие, а длинные)

Подскажите - а вот ваш скрипт добавляет картинку с жестко заданными размерами 75х75:
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $sRead = FileRead(@ScriptDir & '\Тестовые вопросы и ответы.txt')
Global $aData = StringRegExp($sRead, '(?s)(Вопрос \d+\r?\n[^\r\n]+\r?\n(?:Адрес:\r?\n[^\r\n]+\r?\n)?Ответы:\r?\n.*?\r?\nПравильный:\r?\n[^\r\n]+)', 3)
Global $aQuestion_Bttn[10], $iQuestion_Lbl, $iImage_Pic, $sCorret_Answer
Global $iTimer

Global $iCrctAnswr_Sleep = 10 ;Minutes
Global $iInCrctAnswr_Sleep = 1 ;Minutes

Opt('TrayMenuMode', 1)
TraySetState(2)

$hGUI = GUICreate('Questions', 250, 400)

$iStatus_Lbl = GUICtrlCreateLabel('', 20, 370, 210, 30)
GUICtrlSetColor(-1, 0xFF0000)

_Questions_SetRandom()

GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    
    Switch $nMsg
        Case 0
            ContinueLoop
        Case $GUI_EVENT_CLOSE
            Exit
        Case $aQuestion_Bttn[1] To $aQuestion_Bttn[9]
            If GUICtrlRead($nMsg) = $sCorret_Answer Then
                TraySetState(1)
                GUISetState(@SW_HIDE)
                Sleep(1000 * 60 * $iCrctAnswr_Sleep)
                GUISetState(@SW_SHOW)
                TraySetState(2)
            Else
                $iTimer = TimerInit()
                AdlibRegister('_Status_Timer', 1000)
                _Status_Timer()
                
                _Questions_SetState($GUI_DISABLE)
                Sleep(1000 * 60 * $iInCrctAnswr_Sleep)
                _Questions_SetState($GUI_ENABLE)
                
                AdlibUnRegister('_Status_Timer')
                GUICtrlSetData($iStatus_Lbl, '')
            EndIf
            
            _Questions_SetRandom()
    EndSwitch
WEnd

Func _Status_SetData($sData)
    If GUICtrlRead($iStatus_Lbl) <> $sData Then
        GUICtrlSetData($iStatus_Lbl, $sData)
    EndIf
EndFunc

Func _Status_Timer()
    _Status_SetData('Неверный ответ, до нового вопроса осталось: ' & (($iInCrctAnswr_Sleep * 60) - Round(TimerDiff($iTimer) / 1000)) & ' сек.')
EndFunc

Func _Questions_SetRandom()
    Local Static $fFirst = True
    Local Static $iLast_Random
    
    Local $iRandom
    
    Do
        $iRandom = Random(0, UBound($aData) - 1, 1)
    Until $iRandom <> $iLast_Random
    
    $iLast_Random = $iRandom
    
    Local $sQuestion = StringRegExpReplace($aData[$iRandom], '(?s)Вопрос \d+\r?\n([^\r\n]+).*', '\1')
    Local $aQuestions = StringSplit(StringStripCR(StringRegExpReplace($aData[$iRandom], '(?s).*?Ответы:\r?\n(.*?)\r?\nПравильный:.*', '\1')), @LF)
    Local $aAddress = StringRegExp($aData[$iRandom], '(?s).*?Адрес:\r?\n([^\r\n]+)\r\n?Ответы:.*', 3)
    
    $sCorret_Answer = StringRegExpReplace($aData[$iRandom], '(?s).*?\r?\nПравильный:\r?\n([^\r\n]+)', '\1')
    
    If $fFirst Then
        $fFirst = False
        $iQuestion_Lbl = GUICtrlCreateLabel('', 20, 20, 200, 25)
        
        For $i = 1 To 9
            $aQuestion_Bttn[$i] = GUICtrlCreateButton('', 20, $i * 45, 200, 20)
            GUICtrlSetState($aQuestion_Bttn[$i], $GUI_HIDE)
        Next
        
        $iImage_Pic = GUICtrlCreatePic('', 85, 290, 75, 75)
    EndIf
    
    GUICtrlSetData($iQuestion_Lbl, $sQuestion)
    
    For $i = 1 To 9
        GUICtrlSetData($aQuestion_Bttn[$i], '')
        GUICtrlSetState($aQuestion_Bttn[$i], $GUI_HIDE)
    Next
    
    For $i = 1 To $aQuestions[0]
        GUICtrlSetData($aQuestion_Bttn[$i], $aQuestions[$i])
        GUICtrlSetState($aQuestion_Bttn[$i], $GUI_SHOW)
    Next
    
    If IsArray($aAddress) Then
        GUICtrlSetState($iImage_Pic, $GUI_SHOW)
        GUICtrlSetImage($iImage_Pic, $aAddress[0])
    Else
        GUICtrlSetState($iImage_Pic, $GUI_HIDE)
    EndIf
EndFunc

Func _Questions_SetState($iState)
    For $i = 1 To 9
        If $aQuestion_Bttn[$i] Then
            GUICtrlSetState($aQuestion_Bttn[$i], $iState)
        EndIf
    Next
EndFunc

А как поменять эту часть кода:
Код:
$iImage_Pic = GUICtrlCreatePic('', 85, 290, 75, 75)

, чтобы картинка имела размер 75 - лишь только по ширине, а ее длина - изменялась бы в соответствии с имеющимися у нее пропорциями ?
(Потому что сейчас картинка искажается. А если бы размер задавался только по одной стороне, то искажений бы не было.)
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
SergVrn [?]
если бы размер задавался только по одной стороне, то искажений бы не было
Кто рисует картинки? Я так понимаю что ты, так и рисуй их пропорционально )).
Искажение будет если нет соотношения сторон, не важно по ширине или по высоте.
Тут нужно рисовать изображение другими методами.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Можно примеры таких изображений?
 
Автор
S

SergVrn

Новичок
Сообщения
87
Репутация
2
CreatoR
Я не рисую эти картинки.
Это фотографии.


Добавлено:
Сообщение автоматически объединено:

CreatoR [?]
Можно примеры таких изображений?

Вот такой пример:
(Здесь как раз ширина и длина не равны. Поэтому так важно сохранить пропорции)
 

Вложения

  • Image 1.png
    Image 1.png
    177.6 КБ · Просмотры: 2

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
SergVrn
Все изображения имеют ширину больше чем высоту?
 
Автор
S

SergVrn

Новичок
Сообщения
87
Репутация
2
CreatoR
Все изображения имеют ширину больше чем высоту?

Нет иногда ширина - меньше чем высота.
Вот например на этой фотографии.

Вопрос здесь - как большую сторону картинки - всегда уменьшать до 75 ?
Чтобы картинка - пропорционально становилась меньше.
 

Вложения

  • Image 7.png
    Image 7.png
    134.9 КБ · Просмотры: 6
Автор
S

SergVrn

Новичок
Сообщения
87
Репутация
2
Как же решить этот непростой вопрос ?
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
SergVrn [?]
Как же решить этот непростой вопрос ?
искать по форуму. уже давно большинство вопросов решены или есть варианты решения
Изменение размера картинки
но пропорции картинок все равно разные, даже после уменьшения
как вариант, подгонять размер элемента "картинка" под размер изображения. тогда не будет искажений
пример
Код:
#include <WinAPIex.au3>
#include <Icons.au3>

Local $Form1 = GUICreate("Form1", 615, 437, -1, -1)
Local $Pic1 = GUICtrlCreatePic("", 48, 32, 332, 308)
Local $BT = GUICtrlCreateButton("OK", 400, 32, 70, 30)
GUISetState()
Local $hImage, $sPath, $Width, $Height

While 1
	Switch GUIGetMsg()
		Case -3
			Exit
		Case $BT
			$sPath = FileOpenDialog('', '', '(*.jpg;*.png)', 0, '', $Form1)
			If Not @error Then
				_GDIPlus_Startup()
				$hImage = _GDIPlus_ImageLoadFromFile($sPath)
				$Width = _GDIPlus_ImageGetWidth($hImage)
				$Height = _GDIPlus_ImageGetHeight($hImage)
				_GDIPlus_ImageDispose($hImage)
				_GDIPlus_Shutdown()
				GUICtrlSetPos($Pic1, Default, Default, $Width, $Height)
				_SetImage($Pic1, $sPath, $Width, $Height)
			EndIf
	EndSwitch
WEnd
в этом коде используется Icons.au3 с небольшим редактированием
 

Вложения

  • Icons.au3
    35.8 КБ · Просмотры: 3

Tempo

AutoIT Гуру
Сообщения
616
Репутация
205
Больше похоже на тему для Стол заказов
Код:
#NoTrayIcon
#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <WinAPISysWin.au3>
#include <Math.au3>
#include <TrayConstants.au3>
#include <MsgBoxConstants.au3>
Opt("TrayAutoPause", 0)
Opt("GUIOnEventMode", 1)
Opt("GUIResizeMode", $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKMENUBAR)

Global Const $GUI_TITLE = "Тест"
Global Const $QUESTION_FILE = @ScriptDir & "\Тестовые вопросы и ответы.txt"
Global Const $ANSWER_CORRECT_PAUSE = 10 ;мин.
Global Const $ANSWER_INCORRECT_PAUSE = 1 ;мин.

Global Const $GUI_WIDTH = 325
Global Const $PIC_SIZE = 75
Global Const $PIC_ONLYREDUCE = False
Global Const $LABEL_HEIGHT = 20
Global Const $BUTTON_HEIGHT = 30
Global Const $CONTROL_INDENT = 10

Global Enum $TST_QUESTION, $TST_CORRECT, $TST_PIC, $TST_ANSWERS, $TST_MAX
Global Enum $ANS_ID, $ANS_TEXT, $ANS_MAX
Global $g_hGUI, $g_idQuest, $g_idInfo, $g_idPic, _
		$g_aTest[][$TST_MAX] = [[0, -1]], $g_hTimer

_GUI_Init()
_Test_Init()
_Test_Start()

While Sleep(10)
WEnd

Func _GUI_Init()
	$g_hGUI = GUICreate($GUI_TITLE, $GUI_WIDTH)
	GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

	Local $iY = $CONTROL_INDENT, $iFullWidth = $GUI_WIDTH - $CONTROL_INDENT * 2
	$g_idQuest = GUICtrlCreateLabel("", $CONTROL_INDENT, $iY, $iFullWidth, $LABEL_HEIGHT, BitOR($SS_CENTERIMAGE, $SS_CENTER))
	$iY += $LABEL_HEIGHT + $CONTROL_INDENT
	$g_idPic = GUICtrlCreatePic("", ($GUI_WIDTH - $PIC_SIZE) / 2, $iY, $PIC_SIZE, $PIC_SIZE, $SS_CENTERIMAGE)
	GUICtrlSetState(-1, $GUI_HIDE)
	$iY += $PIC_SIZE + $CONTROL_INDENT
	$g_idInfo = GUICtrlCreateLabel("", $CONTROL_INDENT, $iY, $iFullWidth, $LABEL_HEIGHT, BitOR($SS_CENTERIMAGE, $SS_CENTER))
	GUICtrlSetColor(-1, 0xFF0000)
	GUICtrlSetState(-1, $GUI_HIDE)
EndFunc   ;==>_GUI_Init

Func _Test_Init()
	Local $sRead = FileRead($QUESTION_FILE)
	Local $aData = StringRegExp($sRead, "(?i)Вопрос \d+\R(.+?)\R((?s).+?)\RПравильный:\R(.+)", $STR_REGEXPARRAYGLOBALMATCH)
	If @error Then Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, $GUI_TITLE, StringFormat('Вопросы не найдены -> "%s"', $QUESTION_FILE))
	Local $iIdx, $iCount = UBound($aData)
	Dim $g_aTest[$iCount / 3 + 1][$TST_MAX] = [[0, -1]]
	For $i = 0 To $iCount - 1 Step 3
		$g_aTest[0][0] += 1
		$iIdx = $g_aTest[0][0]

		$g_aTest[$iIdx][$TST_QUESTION] = $aData[$i]
		$g_aTest[$iIdx][$TST_CORRECT] = $aData[$i + 2]
		_Test_MakeSubData($aData[$i + 1])
	Next
EndFunc   ;==>_Test_Init

Func _Test_MakeSubData($sData)
	Local $aSubData, $iIdx = $g_aTest[0][0], $iOffset = 1
	$aSubData = StringRegExp($sData, "(?i)Адрес:\R(.+)", $STR_REGEXPARRAYMATCH)
	If Not @error Then
		$g_aTest[$iIdx][$TST_PIC] = $aSubData[0]
		$iOffset = @extended
	EndIf

	Local $aSplit, $sAnswers = "Некорректный вопрос (без ответов)", $bCorrect
	$aSubData = StringRegExp($sData, "(?i)Ответы:\R((?s).+)", $STR_REGEXPARRAYMATCH, $iOffset)
	If Not @error Then $sAnswers = $aSubData[0]
	$aSplit = StringSplit(StringStripCR($sAnswers), @LF)
	Local $aAnswers[$aSplit[0] + 1][$ANS_MAX] = [[$aSplit[0]]]
	For $i = 1 To $aSplit[0]
		$aAnswers[$i][$ANS_TEXT] = $aSplit[$i]
		If Not $bCorrect Then $bCorrect = $g_aTest[$iIdx][$TST_CORRECT] = $aAnswers[$i][$ANS_TEXT]
	Next
	If Not $bCorrect Then MsgBox($MB_ICONERROR + $MB_TOPMOST, $GUI_TITLE, StringFormat('Верный ответ не найден -> "%s"', $g_aTest[$iIdx][$TST_QUESTION]))
	$g_aTest[$iIdx][$TST_ANSWERS] = $aAnswers
EndFunc   ;==>_Test_MakeSubData

Func _Test_Start()
	Local $iIdx = $g_aTest[0][1]
	Do
		$iIdx = Random(1, $g_aTest[0][0], 1)
	Until $iIdx <> $g_aTest[0][1]

	GUICtrlSetData($g_idQuest, $g_aTest[$iIdx][$TST_QUESTION])
	Local $iY = $CONTROL_INDENT * 2 + $LABEL_HEIGHT, $iFullWidth = $GUI_WIDTH - $CONTROL_INDENT * 2
	If $g_aTest[$iIdx][$TST_PIC] Then
		_GUICtrlPic_SetImageWithResize($g_idPic, $g_aTest[$iIdx][$TST_PIC], $PIC_ONLYREDUCE)
		GUICtrlSetState($g_idPic, $GUI_SHOW)
		$iY += $PIC_SIZE + $CONTROL_INDENT
	Else
		GUICtrlSetState($g_idPic, $GUI_HIDE)
	EndIf
	$aAnswers = $g_aTest[$iIdx][$TST_ANSWERS]
	For $i = 1 To $aAnswers[0][0]
		$aAnswers[$i][$ANS_ID] = GUICtrlCreateButton($aAnswers[$i][$ANS_TEXT], $CONTROL_INDENT, $iY, $iFullWidth, $BUTTON_HEIGHT)
		GUICtrlSetOnEvent(-1, "_Test_Proc")
		$iY += $BUTTON_HEIGHT + $CONTROL_INDENT
	Next
	$g_aTest[$iIdx][$TST_ANSWERS] = $aAnswers
	GUICtrlSetPos($g_idInfo, Default, $iY)
	$iY += $BUTTON_HEIGHT + $LABEL_HEIGHT + $CONTROL_INDENT
	WinMove($g_hGUI, "", Default, $g_aTest[0][1] == -1 ? (@DesktopHeight - $iY) / 2 : Default, Default, $iY)
	$g_aTest[0][1] = $iIdx
	GUISetState()
EndFunc   ;==>_Test_Start

Func _Test_Proc()
	Local $iIdx = $g_aTest[0][1], $aAnswers
	If GUICtrlRead(@GUI_CtrlId) = $g_aTest[$iIdx][$TST_CORRECT] Then
		GUISetState(@SW_HIDE)
		$aAnswers = $g_aTest[$iIdx][$TST_ANSWERS]
		For $i = 1 To $aAnswers[0][0]
			GUICtrlDelete($aAnswers[$i][$ANS_ID])
		Next
		TraySetState($TRAY_ICONSTATE_SHOW)
		Sleep($ANSWER_CORRECT_PAUSE * 1000 * 60)
		TraySetState($TRAY_ICONSTATE_HIDE)
		_Test_Start()
	Else
		_Test_SetState($GUI_DISABLE)
		$g_hTimer = TimerInit()
		GUICtrlSetState($g_idInfo, $GUI_SHOW)
		AdlibRegister("_Test_Timer")
	EndIf
EndFunc   ;==>_Test_Proc

Func _Test_SetState($iState)
	Local $iIdx = $g_aTest[0][1], $aAnswers = $g_aTest[$iIdx][$TST_ANSWERS]
	For $i = 1 To $aAnswers[0][0]
		GUICtrlSetState($aAnswers[$i][$ANS_ID], $iState)
	Next
EndFunc   ;==>_Test_SetState

Func _Test_Timer()
	Local $sInfo = StringFormat("Неверный ответ, до нового вопроса осталось: %i сек.", $ANSWER_INCORRECT_PAUSE * 60 - Round(TimerDiff($g_hTimer) / 1000))
	If GUICtrlRead($g_idInfo) <> $sInfo Then GUICtrlSetData($g_idInfo, $sInfo)
	If TimerDiff($g_hTimer) >= $ANSWER_INCORRECT_PAUSE * 1000 * 60 Then
		AdlibUnRegister("_Test_Timer")
		GUICtrlSetState($g_idInfo, $GUI_HIDE)
		_Test_SetState($GUI_ENABLE)
	EndIf
EndFunc   ;==>_Test_Timer

Func _GUICtrlPic_SetImageWithResize($idPic, $sFile, $bOnlyReduce = True)
	Local $tRect, $iPicW, $iPicH
	$tRect = _WinAPI_GetWindowRect(GUICtrlGetHandle($idPic))
	$iPicW = DllStructGetData($tRect, "Right") - DllStructGetData($tRect, "Left")
	$iPicH = DllStructGetData($tRect, "Bottom") - DllStructGetData($tRect, "Top")
	_GDIPlus_Startup()
	Local $hImage, $iImageW, $iImageH, $iScale, $hImageSc, $hHBMP, $hPrevImage
	$hImage = _GDIPlus_BitmapCreateFromFile($sFile)
	$iImageW = _GDIPlus_ImageGetWidth($hImage)
	$iImageH = _GDIPlus_ImageGetHeight($hImage)
	$iScale = _Min($iPicW / $iImageW, $iPicH / $iImageH)
	If $bOnlyReduce Then $iScale = _Min($iScale, 1)
	$hImageSc = _GDIPlus_ImageScale($hImage, $iScale, $iScale)
	$hHBMP = _GDIPlus_BitmapCreateDIBFromBitmap($hImageSc)
	$hPrevImage = GUICtrlSendMsg($idPic, $STM_SETIMAGE, 0, $hHBMP)
	If $hPrevImage Then _WinAPI_DeleteObject($hPrevImage)
	_GDIPlus_BitmapDispose($hImage)
	_GDIPlus_BitmapDispose($hImageSc)
	_WinAPI_DeleteObject($hHBMP)
	_GDIPlus_Shutdown()
EndFunc   ;==>_GUICtrlPic_SetImageWithResize

Func _Exit()
	Exit
EndFunc   ;==>_Exit
 
Автор
S

SergVrn

Новичок
Сообщения
87
Репутация
2
Tempo
Понятно, спасибо.
И вообще спасибо всем отвечающим в этой теме.
 
Верх