Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Ordner überwachen und Bilder anzeigen (benötige optimierung)


  • Please log in to reply
15 replies to this topic
fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012
Hallo zusammen,

ich komm nicht weiter.

Mein Script überwacht einen Ordner. Landen in diesem Ordner *.png bilder so öffnet sich eine GUI. Soweit so gut. Das klappt auch wunderbar. Aber was wenn es mehr als ein png in dem überwachten Order gibt? Ich weiß nicht wie ich damit umgehen muss. Momentan komme ich an ein andere Bild nur wenn ich die Gui schließe oder den Löschen-Button betätige. Erst wenn ich alle Bilder einmal gesehen habe, wird die Liste neu erstellt. Neue Bilder sind dann irgendwo in der Liste weil diese von a-z gesammelt werden.

Es funktioniert so wie es jetzt ist, aber es ist nicht besonders gut zu handeln. Ich bin mit meinem können aber am Ende. Ich bitte euch daher mir zu helfen.

Wie kann man das besser lösen? So dass man in der GUI einen hinweis auf ein neues Bild bekommt und dieses per klick anzeigen lassen kann... so das man zwischen allen anderen aber nicht nach a-z sortiert sondern nach eingangsdatum sortiert hin und her wechseln kann.

Hier mein Code bisher:

Spoiler


Die PNG Bilder sind in diesem Format: A_UserName "-" PicToUser "-screenshot-" A_Now ".png" - PicToUser ist dabei der Username des Empfängers.

Ih hoffe ihr könnt mir weiterhelfen. Ich sitz schon ein paar stunden hier und weiß nicht wie ich weiterkommen soll.

MfG
fump

IsNull
  • Moderators
  • 990 posts
  • Last active: May 15 2014 11:56 AM
  • Joined: 10 May 2007
Zunächst solltest du dir mal genau überlegen wie du das ganze haben willst. Darauf kommst du, in dem du dir den Ablauf mal vorstellst, und evtl Skizzen machst.

Danach kannst du die einzelnen GUI Elemente bauen, so dass sie dem entsprechen was du willst.

Und zum Schluss musst du dir das Datenmodell überlegen, damit du deine Liste handhaben kannst. Da dürfte die AHK Arrays/Listen komplett ausreichend sein.

strobo
  • Members
  • 359 posts
  • Last active: Mar 10 2015 08:13 PM
  • Joined: 19 Jun 2012
So könntest du nach a_loopfiletimemodified ordnen
sFilePattern:="*.png"
loop,% sFilePattern
sFileList.=a_loopfiletimemodified a_loopfilename "`n"

sFileList:=rtrim(sFileList,"`n")
sort,sFileList,R
sFileList:=regexreplace(sFileList,"m`n)^\d{14}")
msgbox,% sFileList
In
A_UserName "-" PicToUser "-screenshot-" A_Now ".png"
kann man wohl das
-" A_Now "
weglassen und anstelle dessen filegettime o.ä. benutzen. Im script fehlt auch eine funktion, sodass man es nicht testen kann. Bei Gui bin ich nicht so bewandert, aber mir fällt dieses ListView Bsp aus der Hilfe ein:
; Create the ListView with two columns, Name and Size:
Gui, Add, ListView, r20 w700 gMyListView, Name|Size (KB); Gather a list of file names from a folder and put them into the ListView:
Loop, %A_MyDocuments%\*.*
LV_Add("", A_LoopFileName, A_LoopFileSizeKB)

LV_ModifyCol() ; Auto-size each column to fit its contents.
LV_ModifyCol(2, "Integer") ; For sorting purposes, indicate that column 2 is an integer.; Display the window and return. The script will be notified whenever the user double clicks a row.
Gui, Show
return
MyListView:
if A_GuiEvent = DoubleClick
{
LV_GetText(RowText, A_EventInfo) ; Get the text from the row's first field.
ToolTip You double-clicked row number %A_EventInfo%. Text: "%RowText%"
}
return
GuiClose: ; Indicate that the script should exit automatically when the window is closed.
ExitApp
anstatt
Loop, %A_MyDocuments%\*.*
nimmste vllt
loop,parse,sFileList,`n
und
ToolTip You double-clicked row number %A_EventInfo%. Text: "%RowText%"
ersetzte durch code für "Zeig die Datei RowText an".
Regards,
Babba

fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012
hier mal das komplette script... Im grund weiß ich genau wie ich es haben will... ich weiß nur nicht wie ich es umsetzen soll...

funktionen.ini
[PicChat]
PicChatAutoLogin=1
PicChatAutoGUI=1
PicChatStoragePfad=E:\PicChat\PicShare
UserPfad=E:\PicChat\Bildsafe

PicChat.ahk - zeigt eine Gui mit Listview wo benutzer erscheinen die "Online" sind. Bei Doppelklick wird geprüft ob sie noch aktiv sind und wenn ja kann man ein BIld erstellen (Screenshot, Bildausschnit) dieser wird dann im Order des Users abgelegt den man doppelt angeklickt hat. Bei dem User öffnet sich dann auch die besagte GUI die das Bild anzeigt. Es funktioniert... Aber eben nicht so Userfreundlich. Für 1 Bild ausreichend. Aber für mehr machts keinen Sinn so... leider Fehlt mir das Wissen dies zu ändern.
Spoiler


Um das ganze besser testen zu können habe ich noch einen Emulator dahingeklatscht. Der Code ist sicherlich Optimierungsbedürftig aber es reicht um das eigentliche Script zu testen. Der Bildempfang und das anzeigen des Bildes funktioniert in diesem Emulator "noch" nicht Posted Image

Spoiler


Hier das ganze als Paket mit samt Ordner uns user.ini und GDI+.

http://www.file-uplo...icChat.zip.html

Ich hoffe das Ihr euch so ein besseres Bild machen könnt.

MfG
fump

//EDIT:
Die GUI die das Bild anzeigt, diese um ein Listview zu erweitern in dem dann die Bilder die man erhalten hat gesammelt werden, bei doppelklick dann verkleinert dargestellt... Das wäre doch ne gute Lösung oder? Ich glaube das hat Babba auch gemeint oder?

Edited by fump2000, 26 November 2012 - 01:25 PM.


strobo
  • Members
  • 359 posts
  • Last active: Mar 10 2015 08:13 PM
  • Joined: 19 Jun 2012
Ja, hat er wohl;)
aber ein script sagt mehr als tausend worte:
sFilePattern:=PicChatStoragePfad "\" A_UserName "\*.png"
needle:="^(.+)-(.+)-\w+-(\d+)\.\w+$"
Gui, Add, ListView, r20 w200 gMyListView, Name|Sender|Time
Loop,% sFilePattern
    if (regexmatch(a_loopfilename,needle,match) && match2=a_username)
        LV_Add("", A_LoopFileFullPath,match1,match3)

LV_ModifyCol()
LV_ModifyCol(1,0)
Gui, Show
return
MyListView:
    if (A_GuiEvent="DoubleClick")
        {
        LV_GetText(Picture, A_EventInfo)
        run,% Picture
        }
    return
GuiClose:
    Exitapp
    return
Ist nur als ansatz gedacht, ist quasi meine erste gui geschichte.
Achja, unter ExistPic haste ein winwaitclose, fehlt davor vllt ein winclose?
Regards,
Babba

fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012
Hi babba :) Danke dir für das Script!!!

Kannst du mir bitte diese Zeile erklären?
needle:="^(.+)-(.+)-\w+-(\d+)\.\w+$"

Was macht die? Wozu ist sie da?

nnnik
  • Members
  • 1625 posts
  • Last active: Jan 24 2019 02:19 PM
  • Joined: 28 Jul 2012
Needle bestimmt wonach beim RegExMatch, in einer der folgenden Zeile, gesucht werden soll.
Die Zeichen haben, glaube ich ,alle Sonderfunktionen.
Mehr findest du in der Hilfe zu Reguläre Ausdrücke.
Hier die die du brauchst:

^ kann am Anfang eines Musters stehen, damit die Übereinstimmung ganz am Anfang einer Zeile erfolgt. Zum Beispiel stimmt ^abc mit abc123 überein, aber nicht mit 123abc.


(...) Elemente in Klammern werden häufig verwendet, um einen Teilausdruck wie der Punkt-Stern in abc(.*)xyz einzufangen. Zum Beispiel speichert RegExMatch() den Teilstring, der mit jedem Teilausdruck übereinstimmt, in einem Ausgabe-Array. Ebenso kann RegExReplace() den Teilstring, der mit jedem Teilausdruck übereinstimmt, in das Ergebnis per Rückreferenz (z. B. $1) wieder einfügen. Damit die Klammern den Teilausdruck nicht einfangen, müssen die ersten beiden Zeichen innerhalb der Klammern ?: sein, zum Beispiel: (?:.*)

. Standardmäßig stimmt ein Punkt mit jedem Zeichen überein, das nicht zu einer Zeilenumbruchsreihe (`r`n) gehört. Dieses Verhalten kann jedoch geändert werden, wenn die Optionen DotAll (s), LF (`n), CR (`r), `a oder (*ANYCRLF) verwendet werden. Zum Beispiel stimmt ab. mit abc und abz und ab_ überein.

+ Mit dem Pluszeichen darf das voranstehende Element (Zeichen, Klasse oder Teilausdruck) ein- oder mehrmals vorkommen. Zum Beispiel stimmt a+ mit ab und aaab überein. Aber im Gegensatz zu a* und a? stimmt das Muster a+ nicht mit dem Anfang eines Strings überein, dem ein "a"-Zeichen fehlt.

\w Stimmt mit jedem "Wort"-Zeichen überein, nämlich alphanumerisch oder Unterstrich. Das ist gleichbedeutend mit [a-zA-Z0-9_]. Umgekehrt bedeutet das großgeschriebene \W: "jedes Zeichen, dass kein Wort-Zeichen ist".

\d Stimmt mit jeder Ziffer überein (entspricht der Klasse [0-9]). Umgekehrt bedeutet das großgeschriebene \D: "jedes Zeichen, dass keine Ziffer ist". Dieser und die anderen zwei Buchstaben können in einer Klasse verwendet werden, zum Beispiel bedeutet [\d.-]: "jede Ziffer, jeder Punkt oder jedes Minuszeichen".

\ Schutzzeichen: Die meisten Zeichen wie abc123 können direkt in einem regulären Ausdruck verwendet werden. Allerdings müssen die Zeichen \.*?+[{|()^$ mit einem Backslash vorangestellt werden, damit sie direkt verwendet werden. Zum Beispiel ist \. ein direkt vorhandener Punkt und \\ ist ein direkt vorhandener Backslash. Das Schützen kann mit \Q...\E verhindert werden. Zum Beispiel: \QDirekt vorhandener Text\E.

$ kann am Ende eines Musters stehen, damit die Übereinstimmung ganz am Ende einer Zeile erfolgt. Zum Beispiel stimmt abc$ mit 123abc überein, aber nicht mit abc123.

Damit solltest du es dir erklären können.
Du musst dafür aber ein bisschen nachdenken.

Visit the new forum ahkscript.org.

http://ahkscript.org


fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012
^(.+)-(.+)-\w+-(\d+)\.\w+$

würde diesen Dateinamen: horsgumb-dietmaie-screenshot-20121126000518.png folgendermaßen zerlegen...

^ = vom Anfang ausgehend
(.+) = horsgumb, wird in einem Ausgabe-Array gespeichert
-
(.+) = dietmaie, wird in einem Ausgabe-Array gespeichert
-
\w+ = Jedes Wortzeichen also "screenshot"
-
(\d+) = 20121126000518 = der Timestemp wann das Bild erstellt wurde.
.
\w+$ = png

Das $ am ende wäre aber eigentlich nicht nötig oder?

if (regexmatch(a_loopfilename,needle,match) && match2=a_username)
LV_Add("", A_LoopFileFullPath,match1,match3)
Hier wird also der Dateiname zerlegt, match ist = horsgumb match 2 (also dietmaie) wird geprüft ob es mit A_UserName übereinstimmt, wenn nicht wird es dem Listview nicht hinzugefügt. Passt der vergleich wird das Listview gefüllt mit dem Pfad, den namen des Senders und dem Zeitstempel.

Korrekt so?

:)

strobo
  • Members
  • 359 posts
  • Last active: Mar 10 2015 08:13 PM
  • Joined: 19 Jun 2012
Japp korrekt,
ohne \.\w+$ würds bei "deinen" dateinamen (wahrsch. alle gleich formatiert) auch funzen. Je genauer man mit der needle am format ist, desto weniger Fremdfang hat man im allgemeinen und es ist auch leichter zu lesen;)
Regards,
Babba

fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012
Vielen Dank!

Werd versuchen das ganze etwas anders darzustellen und Poste dann das Ergebnis :)

MfG
fump

fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012
Fragen:
Wie bekommt man die ListView nach Time sortiert? So dass der neuste Eintrag oben steht?
Wie kann man einen GUI Flash auslösen wenn ein neuer Eintrag vorhanden ist? Also wie erkennt man, dass da ein Eintrag dazu gekommen ist?

nnnik
  • Members
  • 1625 posts
  • Last active: Jan 24 2019 02:19 PM
  • Joined: 28 Jul 2012
@Frage1
1. Möglichkeit: Du hast das ganze nochmal in einem anderen Array gespeichert und nicht sortiert.
Sobals du es nach der Reihenfolge sortiert haben willst löscht du alle sachen und fügst sie von dem Array neu ein
2. Möglichkeit: Du versiehst alle Reihen mit der Information Zeitpunkt des Hinzufügens.
Dann überlässt du es dem benutzer es nach der Zeit oder nicht zu sortieren
@Frage2
Um Information hinzuzufügen muss eine Funktion / ein Label angesprungen werden was die Info hinzufügt.
Dort einfach den Befehl für das Flashen hizufügen

Visit the new forum ahkscript.org.

http://ahkscript.org


strobo
  • Members
  • 359 posts
  • Last active: Mar 10 2015 08:13 PM
  • Joined: 19 Jun 2012
Wie bekommt man die ListView nach Time sortiert? --> Auf Time-Header klicken.
Für Zeitordnung bei Erstellung der LV über sFileList parsen (s.u.). Hier mal ein Ansatzpunkt zur Ordnerüberwachung (ungetestet) EDITIERT:
CheckFolderLabel:
    txt:=""
    loop,% sFilePattern
        if (regexmatch(a_loopfilename,needle,match) && match2=a_username)
            txt.=match3 a_loopfilefullpath "`n"
    sort,txt,R
    txt:=rtrim(txt,"`n")
    regexmatch(txt,"^\d{14}(.+?)`n",NewFile)
    if (InStr(sFileList,NewFile1))
        return
    ; wenn das script hier ankommt, sollte eine neue datei gefunden worden sein.
    sFileList:=regexreplace(txt,"m`n)^\d{14}") ; zeitgeordnete Liste der Pfade
    ; hier weitere Befehle einfügen.

    return

Regards,
Babba

fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012
Hab nun das hier daraus gemacht:
UserINI:=PicChatStoragePfad "\user.ini"
SearchPfadPNG:=PicChatStoragePfad "\" A_UserName "\*.png"
PicturePfad:=PicChatStoragePfad "\" A_UserName "\"

ExistPic:
Gui, Pic:Default
StartTime:=A_Now
txt:=""
Loop,% SearchPfadPNG
if (regexmatch(a_loopfilename,needle,match) && match2=a_username)
   txt.=match3 a_loopfilename "`n"
   ;a_loopfilefullpath
  sort,txt,R
  txt:=rtrim(txt,"`n")
  if (LastRun!="" && substr(txt,1,14)<LastRun)
  Return
LastRun:=StartTime
sFileList:=regexreplace(txt,"m`n)^\d{14}")
PfadReplace:=
GuiControl, -Redraw, PictureList
LV_Delete()
PicList:=0
Loop, parse, sFileList, % "`n"
if (regexmatch(A_LoopField,needle,match) && match2=a_username)
  {
   If A_LoopField =  ; Ignoriert das leere Element am Ende der Liste.
   break
  
   IniRead, match1, %UserINI%, User, % match1, % match1

   SetPfad:=PicturePfad A_LoopField   FormatTime, match3, %match3% ,dd.MM.yyyy HH:mm
   LV_Add("", SetPfad,match1,match3)
   PicList++
  }
LV_ModifyCol()
LV_ModifyCol(1,0)
GuiControl, +Redraw, PictureList
if (PicList > PicListSafe)
{
  PicListSafe:=PicList
  Loop 6
   {
    Gui Flash
    Sleep, 500
   }
}
Return

In der %UserINI% stehen die Langnamen, diese werden dann in der Listview dargestellt.

Mit dem Flash das funktioniert nicht so richtig... aber ne andere Lösung ist mir nicht eingefallen.

strobo
  • Members
  • 359 posts
  • Last active: Mar 10 2015 08:13 PM
  • Joined: 19 Jun 2012
Hi, ich hab den code mal etwas abgespeckt:
UserINI:=PicChatStoragePfad "\user.ini"
SearchPfadPNG:=PicChatStoragePfad "\" A_UserName "\*.png"
needle:="([^\\]+)-([^\\]+)-\w+-(\d+)\.\w+$"

ExistPic:
    Gui, Pic:Default
    txt:=""
    Loop,% SearchPfadPNG
    if (regexmatch(a_loopfilefullpath,needle,match) && match2=a_username)
       txt.=match3 a_loopfilefullpath "`n"
    
    txt:=rtrim(txt,"`n")
    sort,txt,R
    
    regexmatch(txt,"^\d{14}(.+?)`n",NewFile)
    if (InStr(sFileList,NewFile1))
        return
    
    sFileList:=regexreplace(txt,"m`n)^\d{14}")
    GuiControl, -Redraw, PictureList
    LV_Delete()
    Loop, parse, sFileList,% "`n"
        if (regexmatch(A_LoopField,needle,match))
            {
            IniRead, match1,% UserINI, User,% match1
            FormatTime, match3,% match3, dd.MM.yyyy HH:mm
            LV_Add("",A_LoopField,match1,match3)
            }
    
    LV_ModifyCol()
    LV_ModifyCol(1,0)
    GuiControl, +Redraw, PictureList

    Loop,6
        {
        Gui Flash
        Sleep, 500
        }
    Return
Die Funktionalität (incl. aller Probleme) sollte erhalten sein. Mit nem spezifischem gui-topic bekommste vllt schneller gui-hllfe.
Regards,
Babba