04/07/2000
At skabe en robust og intuitiv brugergrænseflade (UI) er en afgørende del af ethvert automatiseret testsystem. Den giver operatører og ingeniører et vindue ind til testprocessen, så de kan starte sekvenser, overvåge status og se resultater. National Instruments' TestStand leveres med et fremragende eksempel på en simpel brugergrænseflade bygget i LabVIEW, som fungerer som en perfekt skabelon og læringsressource. Denne artikel dykker ned i arkitekturen og funktionaliteten af denne simple brugergrænseflade, som kan findes i mappen (<TestStand>\UserInterfaces\Simple\LabVIEW\). Vi vil dissekere dens opbygning i faser for at give en klar forståelse af, hvordan man bygger og tilpasser sine egne TestStand-brugergrænseflader.

Den Grundlæggende Arkitektur: Manager Controls
Før vi dykker ned i koden, er det vigtigt at forstå det centrale koncept, som TestStand UI'er er bygget op omkring: Manager Controls. Disse er ActiveX-kontrolelementer, der fungerer som et mellemlag mellem din LabVIEW-kode og den kraftfulde TestStand-motor. De abstraherer en stor del af den komplekse interaktion med TestStand API'en og gør det markant lettere at udvikle en UI. De tre primære manager controls, du vil støde på, er:
- ApplicationManager: Håndterer begivenheder og kommandoer på applikationsniveau, såsom login, afslutning af programmet og åbning af sekvensfiler.
- ExecutionViewManager: Styrer visningen og interaktionen med kørende eksekveringer. Den holder styr på, hvilke tests der kører, og giver mulighed for at pause, stoppe eller afbryde dem.
- SequenceFileViewManager: Håndterer visningen af en sekvensfil, herunder dens trin, variabler og opsætning.
Ved at bruge disse managers kan vi bygge en fuldt funktionel UI ved primært at forbinde vores synlige LabVIEW-kontrolelementer (knapper, lister, indikatorer) til dem og derefter reagere på de hændelser (events), de udsender.
Fase 1: Tilslutning af Synlige Kontrolelementer
Det allerførste, der sker, når brugergrænsefladen starter, er at etablere en forbindelse mellem de synlige kontrolelementer på frontpanelet og de usynlige manager controls i baggrunden. Dette er, hvad der gør UI'en levende. Uden denne forbindelse ville et tryk på en knap eller et valg i en dropdown-menu ikke have nogen effekt. I den simple UI er denne logik typisk samlet i et eller flere subVI'er for at holde koden ren og organiseret.
Konfiguration af ExecutionView Manager
Et godt eksempel er konfigurationen af de kontrolelementer, der er relateret til eksekvering. Her tages referencer til frontpanelelementer som f.eks. en combobox til at vise kørende eksekveringer og knapper til at afbryde eller afslutte dem. Disse referencer sendes til metoder på ExecutionView Manager-objektet.
For eksempel kaldes metoden ConnectExecutionList() med en reference til en combobox. Dette instruerer manageren: "Hver gang listen over aktive eksekveringer ændres, skal du automatisk opdatere indholdet af denne combobox." Det er en kraftfuld en-til-en-forbindelse, der fjerner behovet for manuelt at opdatere listen i en løkke.
For knapper anvendes en mere generisk metode kaldet ConnectCommand(). I stedet for at have en specifik metode for hver mulig knap (ConnectTerminate, ConnectBreak, etc.), tager denne metode en reference til knappen samt en kommando-type (en enum). For eksempel, for at forbinde en "Afslut"-knap, kalder man ConnectCommand() med en reference til knappen og kommandoen CommandKinds_Close. Manageren sørger derefter for, at når brugeren klikker på den knap, udføres den korrekte handling i TestStand-motoren. Denne smarte tilgang gør koden mere skalerbar og lettere at vedligeholde.
| Manager Control | UI-element (Eksempel) | Forbindelsesmetode (Eksempel) | Formål |
|---|---|---|---|
| ExecutionViewManager | "Eksekveringer" Combobox | ConnectExecutionList() | Viser automatisk en liste over alle aktive testeksekveringer. |
| ExecutionViewManager | "Afbryd" Knap | ConnectCommand(CommandKinds_Terminate) | Forbinder knappen til TestStands "Terminate"-funktionalitet. |
| SequenceFileViewManager | Trin-liste (Listbox) | ConnectSequenceView() | Viser trinnene fra den aktuelt indlæste sekvensfil. |
| ApplicationManager | "Afslut" Knap | ConnectCommand(CommandKinds_Exit) | Forbinder knappen til at lukke hele applikationen. |
Fase 2: Konfiguration af Callbacks til TestStand Events
Når forbindelserne er på plads, skal brugergrænsefladen kunne reagere på begivenheder, der opstår i TestStand Engine. En begivenhed kan være, at en bruger åbner en fil, en eksekvering starter, eller der opstår en fejl. Måden, vi håndterer dette på, er ved at registrere Callbacks.
Et callback er essentielt et subVI, som du beder LabVIEW om at køre automatisk, når en bestemt begivenhed indtræffer. I LabVIEW gøres dette ved hjælp af "Register Event Callback"-noden. For hver begivenhed, du vil håndtere, konfigurerer du noden med tre vigtige input:
- Event Kilde: En reference til det objekt, der udsender begivenheden (typisk en af vores manager controls).
- Callback VI Reference: En statisk reference til det subVI, der skal køres, når begivenheden sker.
- User Parameter: En variant, der lader dig sende ekstra data ind i dit callback VI. Dette er ekstremt nyttigt, da det giver dig mulighed for at give callback'en adgang til andre dele af din applikation, som den ellers ikke ville kende til.
Eksempel: DisplaySequenceFile Callback
I den simple UI er der et callback for begivenheden, der sker, når en ny sekvensfil skal vises. Når brugeren åbner en fil, fyrer ApplicationManager en `DisplaySequenceFile`-begivenhed. Denne begivenhed indeholder data, herunder en reference til den fil, der blev åbnet.
Det registrerede callback VI modtager disse event-data. Inde i callback'en bruges denne filreference til at opdatere SequenceFileViewManager. Men hvordan får callback'en fat i referencen til SequenceFileViewManager? Det er her, `User Parameter` kommer i spil. Da vi registrerede callback'en, sendte vi referencen til SequenceFileViewManager med som en user parameter. Callback'en kan nu pakke denne reference ud og bruge den til at kalde en metode, der får UI'en til at vise den nye fil. Dette mønster er fundamentalt for at bygge en skalerbar og modulær UI-arkitektur.
Hjertet af Applikationen: Hovedeventløkken
Efter al konfigurationen er færdig, går applikationen ind i sin hovedløkke. Denne er bygget op omkring en Event Structure i et While Loop. Dette er standardpraksis for at skabe responsive LabVIEW-applikationer, der ikke bruger unødig CPU-kraft, mens de venter på brugerinteraktion.
Interessant nok håndterer denne Event Structure meget få ting i den simple UI. Hvorfor? Fordi de fleste interaktioner (knaptryk, valg i lister) allerede er blevet håndteret af de forbindelser, vi oprettede i fase 1. Manager controls tager sig af det hele i baggrunden.
Hovedeventløkken er dog stadig nødvendig for at håndtere begivenheder, som manager controls ikke kan. Det primære eksempel er, når brugeren lukker vinduet ved at klikke på 'X' i øverste højre hjørne. Dette er en LabVIEW-specifik panelbegivenhed, som TestStand-kontrolelementerne ikke kender til. Event Structure fanger denne "Panel Close?"-begivenhed og sikrer, at applikationen kan lukke ned på en kontrolleret måde.
Derudover bruges den også til at håndtere et brugerdefineret LabVIEW-event, der bruges til at signalere, at programmet skal afsluttes. Dette event bliver typisk udløst inde fra et af TestStand-event-callbacks (f.eks. `ExitApplication`-callback'en). Dette er en elegant måde at kommunikere fra et asynkront kørende callback tilbage til hovedtråden på.
Fase 3: Korrekt Nedlukning
Den sidste fase i en UI's livscyklus er nedlukning. Dette er en kritisk, men ofte overset, del af udviklingen. En ukorrekt nedlukning kan efterlade processer kørende i baggrunden, forårsage hukommelseslækager og skabe problemer, næste gang applikationen startes.
Nedlukningsprocessen i den simple UI består af et par veldefinerede trin, der udføres, efter hovedløkken er stoppet:
- Unregister Events: Alle LabVIEW-events, der blev registreret i starten, skal afregistreres for at frigive referencerne og forhindre, at callback VI'erne bliver i hukommelsen.
- Close References: Alle ActiveX-referencer til manager controls og, vigtigst af alt, til TestStand Engine, skal lukkes. At glemme at lukke motor-referencen er en almindelig fejl, der kan forårsage, at TestStand-processen ikke afsluttes korrekt.
- Exit LabVIEW: Hvis applikationen kører som en bygget eksekverbar fil (.exe), kaldes en "Quit LabVIEW"-funktion til sidst for at lukke processen helt.
Ofte Stillede Spørgsmål (FAQ)
- Hvorfor bruge Manager Controls i stedet for at kalde TestStand API direkte?
- Manager Controls tilbyder et højere abstraktionsniveau, hvilket forenkler udviklingen markant. De håndterer automatisk mange komplekse opgaver som at opdatere kontrolelementers tilstand (f.eks. deaktivere en 'Start'-knap, når en test allerede kører), hvilket ville kræve betydelig mængde brugerdefineret kode, hvis man brugte API'en direkte. De er designet specifikt til at bygge brugergrænseflader.
- Hvad er forskellen på et TestStand Event og et LabVIEW User Event?
- TestStand-events er relateret til testmotorens aktivitet (f.eks. `StartExecution`, `EndStep`). De håndteres via ActiveX-callbacks. LabVIEW User Events er en mekanisme internt i LabVIEW til at sende brugerdefinerede data mellem forskellige dele af et program (f.eks. fra et callback VI til hovedeventløkken) for at afkoble kode og undgå race conditions.
- Kan jeg tilpasse denne Simple User Interface?
- Absolut. Den er designet som et udgangspunkt. Du kan tilføje nye knapper, indikatorer eller helt nye paneler ved at følge de samme principper, som er beskrevet her: tilslut nye UI-elementer til de relevante manager controls og opret nye callbacks for at håndtere brugerdefineret logik.
- Hvad sker der, hvis jeg ikke lukker referencerne korrekt under nedlukning?
- At undlade at lukke referencer, især til TestStand Engine, kan føre til, at LabVIEW-hukommelsen ikke frigives korrekt. I værste fald kan TestStand-processen forblive kørende i baggrunden, selv efter at brugergrænsefladen er lukket, hvilket kan forårsage problemer og kræve, at du manuelt lukker den via Joblisten.
Ved at forstå disse fire faser – tilslutning, callback-konfiguration, event-håndtering og nedlukning – har du fået et solidt fundament for at arbejde med TestStands simple brugergrænseflade. Denne arkitektur er ikke kun effektiv, men også skalerbar, hvilket gør den til en ideel base for at bygge dine egne avancerede og specialiserede testapplikationer i LabVIEW.
Hvis du vil læse andre artikler, der ligner Forstå TestStands Simple UI i LabVIEW, kan du besøge kategorien Teknologi.
