TODO i Mac App Store, med PYQT5 ModelView Architecture för att bygga en enkel TODO -app
ModelView Architecture QT S MVC-liknande gränssnitt för att visa data i vyer
Running -appen visas nedan.
TODO 4+
I flera år använde jag den här applikationen på min iPad, min iPhone och min MacBookpro. Om det fortsätter att fungera perfekt på iOS verkar det som om det inte helt har följt utvecklingen av macOS.
Inga problem att installera det. Men det är inte längre möjligt att synkronisera med Todledo på macOS, medan det fortsätter att vara möjligt på iOS: Samma identifierare erkänns inte.
Det blir därför onödigt för mig … och Appigos hjälp verkar inte ha bråttom att ge ett svar på min begäran. Det är alltid obehagligt att notera att kundkonceptet förlorar lite mer av dess värde varje dag.
Pisa d
Sedan den här uppdateringen har jag tappat alla mina listor i antalet 12 och som jag arbetar dagligen på ett professionellt sätt. Jag hanterar cirka 200 platser permanent, den här uppdateringen har lagt på markmånaderna med prövning ! Alla uppgifter som organiserades i listan befann sig i en enda global lista. Det är verkligen inte detta fel som får mig att gå till versionen som säger professionell av denna programvara annars utmärkt. Jag kommer aldrig att bli fångad. Det återstår bara för mig att vänta på svaret från det stöd som kontaktats i kväll via e -post eller sedan hitta den gamla versionen av denna magnifika programvara. Jag hoppas verkligen att det är en ungdomlig beug av den nya versionen och inte en strategi för att tvinga att migrera till den betalda Pro -versionen för att hitta funktionaliteter som redan har förvärvats med den tidigare versionen. För info gör min synkronisering med Dropbox
Surlepoint, 12/13/2011
Synchro är nu nickel
Jag grep innan synkroniseringen som var långsam, gick dåligt, etc. Men nu med iCloud passar det mig perfekt.
Några möjliga förbättringar: Fler visningsinställningar.
– för att bara visa vad användaren använder. Till exempel använder jag inte sammanhang eller etiketter (i alla fall ännu inte) och jag vill inte längre visa dessa alternativ som “förorenar” min todo. Jag skulle bara vilja ha “Datum / prioritet / lista / typ” för mina vardagliga anteckningar och högerklicka för de alternativ som jag sällan använder
– Och omvänt skulle jag vilja ha en enkel PLSU -display än en drop -down -meny för att välja datum, prioritet, lista, … om jag bara har tre listor, skulle tre knappar räcka för att visas, och jag kunde välja min lista Med ett klick istället för att klicka på Drop -Down -menyn, hitta namnet och klicka på den. (Ditto för prioritering, särskilt att vi går från en mycket visuell ritning på TODO -listan till ett val av namn i alternativen som inte är särskilt naturlig.
Det här är ergonomiska detaljer. Jag gillar enkelheten och effektiviteten i TODO, så jag skulle vilja att det kan vara ännu mer konfigurerbart för att vara ännu enklare.
Integritetsapp
Utvecklaren, Appigo, har inte lämnat information om sin privata praxis och hantering av data till Apple. Mer information finns i utvecklingens integritetspolicy.
ModelView Architecture
QT: s MVC-liknande gränssnitt för att visa data i vyer
När du börjar bygga mer komplexa applikationer med PYQT5 kommer du sannolikt att stöta på widgetar i synkronisering med dina data. Data lagrade i widgetar (E.g. En enkel QlistWidget) är inte lätt tillgänglig för att manipulera från Python – ändringar kräver att du får ett objekt, få data och sedan ställa in dem tillbaka. Standardlösningen på detta är att hålla en extern datarepresentation i Python, och sedan duplicera uppdateringar till både data och widget, eller helt enkelt skriva om wihole -widgeten från data. Detta kan bli ful snabbt och resultera i mycket pannplatta bara för att fikla data.
Tack och lov har Qt en lösning för detta – ModelViews. ModelViews är ett kraftfullt alternativ till standarddisplaywidgets, som använder ett vanligt modellgränssnitt för att interagera med datakällor – från enkla datastrukturer till externa databaser. Detta isolerar dina data, vilket gör att de kan förvaras i alla strukturer du gillar, medan vyn tar hand om presentation och uppdateringar.
Denna handledning introducerar de viktigaste aspekterna av QT: s ModelView Architecture och använder den för att bygga enkla skrivbordsto -applikationer i PYQT5.
Model View Controller
Modell – se – Controller (MVC) är en arkitektonisk mönsteranvändning för utvecklingsanvändargränssnitt som delar upp en applikation i tre sammankopplade delar. Detta skiljer den interna representationen av data från hur information presenteras för och accepterar från användaren.
MVC -designen Pattenn fets tre huvudkomponenter –
- Modell Har den datastruktur som appen arbetar med.
- Se är någon representation av information som visas för användaren, där grafisk eller tabell. Flera vyer av samma datamodell är tillåtna.
- Kontrollera Accepterar inmatning från användaren och förvandlar den till kommandon till för modellen eller vyn.
Det Qt landar skillnaden mellan utsikten och styrenheten blir lite skumma. QT accepterar inmatningshändelser från användaren (via OS) och delegerar dessa till widgets (controller) för att hantera. Widgets hanterar emellertid också presentation av det aktuella tillståndet till användaren, vilket sätter dem kvadratiskt i vyn. I stället för att plåga över var man ska dra linjen, i QT-S-tala är vyn och styrenheten Ilead sammanslagna tog en modell/ViewController-arkitekturkallad “modellvy” för enkelhets skull.
Det är viktigt att skillnaden mellan data och Hur det presenteras bevaras.
Modellvyn
Modellen fungerar som gränssnittet mellan datalagret och ViewController. Modellen har data (eller en hänvisning till den) och presenterar denna data genom ett standardiserat API som sedan konsumerar och presenteras för användaren. Flera vyer kan dela samma data och presentera dem på helt olika sätt.
Du kan använda valfritt “Data Store” för din modell, till exempel en standard Python -lista eller ordbok, eller en databas (via E.g. Sqlalchemy) – det är rätt till dig.
De två delarna är i huvudsak ansvariga för –
- Te modell Lagrar uppgifterna, eller en hänvisning till den och returnerar individuella eller intervall av poster, och tillhörande metadata eller visa instruktioner.
- Te se Begär data från modellen och visar vad som returneras på widgeten.
Det finns en djupgående diskussion om QT-arkitekturen i dokumentationen.
Den kompletta guiden till förpackning Python GUI -applikationer med Pyinstaller.

[[rabatt.Rabatt_pc]]]% rabatt för nästa [rabatt.varaktighet]] [rabatt.Beskrivning]] med koden [rabatt.kupongskod]]
Köpkraftsparitet
Utvecklare i [[land]] få [[rabatt.rabatt_pc]]] av på alla böcker och kurser med kod [rabatt.kupongskod]]
En enkel modellvy – en TODO -lista
För att demonstrera hur man använder ModelViews i praktiken, sätter vi ihop en mycket enkel implementering av en skrivbordslista. Detta kommer att bestå av en QListView för listan över objekt, en QLineEdit för att ange nya objekt och en uppsättning knappar att lägga till, ta bort eller markera objekt enligt gjort.
Användargränssnittet
Det enkla användargränssnittet var ful utflykt QT -skapare och sparad som MainWindow.ui . Te .UI -fil och alla andra delar kan laddas ner nedan.

Designa en enkel TODO -app i Qt -skaparen
Running -appen visas nedan.

Running Todo Gui (ingenting fungerar ännu)
Widgets som finns i gränssnittet som vi gav ID: erna som visas i tabellen nedan.
| objektiv | Snäll | Beskrivning |
|---|---|---|
| todview | Qlistview | Listan över nuvarande Todos |
| todit | QLineEdit | Textingången för att skapa ett nytt TODO -objekt |
| addButton | Qpushbutton | Skapa den nya TODO och lägga till den i Todos -listan |
| deleteButton | Qpushbutton | Ta bort den aktuella valda todo och ta bort den från Todos -listan |
| Komplettbutton | Qpushbutton | Markera den nuvarande valda todo som gjort |
Vi använder dessa identifierare för att ansluta applikationslogiken senare.
Modellen
Vi definierar vår anpassade modell genom att underklassera från implementeringen, vilket gör att vi kan fokusera på de delar som är unika för vår modell. QT levererar ett antal olika modellbaser, inklusive listor, träd och tabeller (idealiska för kalkylblad).
För det här exemplet visar vi resultatet till en qlistview . Den matchande basmodellen för detta är QabstractListModel . Definitionen för vår modell visas nedan.
Klass TODODODEL (Qtcore.QabstractListModel): def __init __ (själv, *args, todos = ingen, ** kwargs): super (todomodel, self).__init __ (*args, ** kwargs) själv.Todos = Todos eller [] def data (själv, index, roll): om roll == qt.DisplayRole: # Se nedan för datastrukturen. status, text = själv.TODOS [index.Rad ()] # returnera TODO -texten endast. Return Text Def RowCount (Self, Index): Return Len (Self.todos)
Te .Todosvariabel är vår datalagra och de två metoderna rowcount () och data () är standardmodellmetoder som vi måste för en listmodell. Vi går igenom dessa i tur och ordning.
.Todoslista
Dataffären för vår modell är .Todos, en enkel pythonlista där vi lagrar en tupel av värden i formatet [(bool, str), (bool, str), (bool, str)] där bool är därför tillstånd för en given post, och STR är TODO: s text.
Vi initialiserar själv.TODO till en tom lista vid start, såvida inte en lista går in via Todos sökordsargument.
själv.Todos = Todos eller [] kommer att sätta mig själv.Todos till det medföljande Todos -värdet om det är trum (i.e. Allt annat än en tom lista, den booleska falska eller ingen standardvärdet), annars kommer det att ställas in på den tomma listan [] .
För att skapa en insida av denna modell kan vi enkelt –
Modell = todomodel () # Skapa en tom TODO -lista
Eller att skicka in en befintlig lista –
Todos = [(falsk, 'ett objekt'), (falsk, 'en annan artikel')] modell = TODODODEL (TODOS)
.RowCount ()
Te .RowCount () -metoden är kallad av vyn för att få antalet rader i de aktuella uppgifterna. Detta krävs för att vyn nu ska maximalt index som det kan göra om datalagret (ROW COUNT-1). Försäljning Vi använder en pythonlista som vår datalagra, returvärdet för detta är helt enkelt len () på listan.
.Data ()
Detta är kärnan i din modell, som hanterar begäran om data från vyn och returnerar lämpligt resultat. Den får två parametrarindex och roll.
Index är positionen/koordinaterna för de data som vyn begär, tillgänglig med två metoder .Rad () och .kolumn () som ger positionen i varje dimension.
För vår QListView är kolumnen alltid 0 och kan ignoreras, men du skulle behöva använda detta för 2D -data i en kalkylbladsvy.
Roll är en flagga som indikerar snäll av data vyn begär. Detta beror på att .Data () -metoden har faktiskt mer ansvar än bara kärndata. Det hanterar också förfrågningar om stilinformation, verktygstips, statusbarer etc. – baserat allt som kan informeras av själva uppgifterna.
Namnet på QT.DisplayRole är lite konstig, men detta indikerar att se frågar oss “snälla ge mig data för display”. Det finns andra roller Som uppgifterna kan ta emot för stylingförfrågningar eller begära data i “redigera-klart” -format.
| Roll | Värde | Beskrivning |
|---|---|---|
| Qt.Visa | 0 | Nyckeldata som ska återkallas i form av text. (QString) |
| Qt.Dekorationrol | 1 | Uppgifterna som ska göras som en dekoration i form av en ikon. (Qcolor, qicon eller qpixmap) |
| Qt.Redaktionell | 2 | Uppgifterna i en formell följd för redigering i en redaktör. (QString) |
| Qt.Verktygstiprol | 3 | Uppgifterna som visas i objektets verktygstips. (QString) |
| Qt.Statusiprol | 4 | Uppgifterna som visas i statusfältet. (QString) |
| Qt.WhatsHisrole | 5 | Uppgifterna som visas för objektet i “Vad är det här?” mode. (QString) |
| Qt.Storlekshintrol | 13 | Storleken tips för objektet som kommer att levereras till vyer. (Qsize) |
För en fullständig lista över tillgängliga roller att du kan få se Qt Itmdatarole -dokumentationen. Vår TODO -lista kommer bara att använda QT.DisplayRole och Qt.Dekorationrol .
Grundläggande implementering
Nedan är den grundläggande stubbapplikationen som behövs för att ladda UI och visa den. Vi lägger till vår modellkod och applikationslogik till denna bas.
Importera Sys från Pyqt5 Importera Qtcore, Qtgui, Qtwidgets, UIC från Pyqt5.Qtcore import qt_creator_file = "mainwindow.ui "ui_mainwindow, qtBaseclass = uic.LoadUduype (qt_creator_file) Klass TODODODEL (Qtcore.QabstractListModel): def __init __ (själv, *args, todos = ingen, ** kwargs): super (todomodel, self).__init __ (*args, ** kwargs) själv.Todos = Todos eller [] def data (själv, index, roll): om roll == qt.DisplayRole: status, text = själv.TODOS [index.Rad ()] return Text def rowcount (self, index): return len (self.Todos) klass MainWindow (Qtwidgets.Qmainwindow, ui_mainwindow): def __init __ (self): qtwidgets.Qumainwindow.__init __ (self) ui_mainwindow.__init __ (själv) själv.Setupui (själv) själv.Modell = todomodel () själv.todview.Setmodel (själv.Modell) app = qtwidgets.QApplication (SYS.Argv) fönster = mainwindow () fönster.Visa () app.Exec_ ()
Vi definierar vår todomodel som tidigare och initialiserar mainwindow -objektet. I __init__ för mainwindow skapar vi en instans av vår TODO -modell och ställer in den här modellen på TODO_VIEW . Spara den här filen som TODO.Py och kör den med –
python3 todo.takt
Även om det inte finns mycket att se ännu, fungerar QListView och vår modell faktiskt – om du lägger till några standarddata ser du att det visas i listan.
själv.Model = TODOMODEL (TODOS = [(FALSE, 'MY FÖRSTA TODO')))))))

QListView som visar hårdkodad TODO-artikel
Du kan fortsätta lägga till artiklar manuellt så här och de kommer att dyka upp i ordning i QListView . Nästa kommer vi att göra det möjligt att lägga till ITMS från applikationen.
Skapa först en ny metod på mainwindow med namnet add . Detta är vår återuppringning som kommer att ta hand om att lägga till den aktuella texten från ingången som en ny todo. Anslut denna metod till addButton.Pressad signal i slutet av __init__ -blocket.
Class MainWindow (QtWidgets.Qmainwindow, ui_mainwindow): def __init __ (self): qtwidgets.Qumainwindow.__init __ (self) ui_mainwindow.__init __ (själv) själv.Setupui (själv) själv.Modell = todomodel () själv.todview.Setmodel (själv.Modell) # Anslut knappen. själv.addButton.Tryck.Connect (self.Lägg till) def add (self): "" Lägg till ett objekt i vår TODO -lista, få texten från QLineEdit .TODOEDIT och där rensar det. "" "Text = själv.todit.Text () Om text: # Lägg inte till tomma strängar. # Komma åt listan via modellen. själv.modell.toddos.Bifoga ((falsk, text)) # trigger uppdatering. själv.modell.skiktad.Emit () # töm ingången själv.todit.SetText ("")
I tilläggsblocket Observera linjen själv.modell.skiktad.Avge () . Här släpper vi ut en modellsignal .layoutchanged för att låta utsikten veta att form av uppgifterna har ändrats. Detta utlöser en uppdatering av synens enhet. Om du utelämnar den här raden kommer TODO fortfarande att läggas till men QListView kommer inte att uppdateras.
Om bara uppgifterna ändras, men antalet rader/kolumner påverkas inte .Datachanged () signal istället. Detta definierar också en förändrad region i uppgifterna med hjälp av en topp-vänster och nedre höger hyra för att undvika att rita om hela vyn.
Ansluter till de andra åtgärderna
Vi kan nu ansluta resten av knappens signaler och lägga till hjälp för prestanda radera och komplett operationer. Vi lägger till knappsignalerna i __init__ -blocket som tidigare.
själv.addButton.Tryck.Connect (self.Lägg till) själv.deleteButton.Tryck.Connect (self.Radera) själv.Komplettbutton.Tryck.Connect (self.Komplett)
Definiera sedan en ny borttagningsmetod enligt följande –
Def delete (self): index = själv.todview.SelectedDindexes () Om Index: # Index är en lista över en enda artikel i enstaka selektioner. Index = index [0] # ta bort objektet och uppdatera. Del själv.modell.TODOS [index.Rad ()] själv.modell.skiktad.Emit () # rensa valet (eftersom det inte är långt giltigt). själv.todview.ClarSelection ()
Vi använder själv.todview.SelectedDindexes för att få indexen (faktiskt en lista över en enda artikel, som vi i envalt läge) och sedan .Rad () som ett index i vår lista över Todos på vår modell. Vi tar bort det indexerade objektet med Pythons del -operatör och utlöser sedan en layoutchanged signal eftersom formen på data har modifierats.
Finally rensar vi det aktiva urvalet eftersom objektet det hänför sig till maj nu utanför gränserna (om du hade valt det sista objektet).
Du kan försöka göra denna smartter och välja det sista objektet i listan istället
Den kompletta metoden gillar så här –
Def komplett (själv): index = själv.todview.SelectredIndexes () om index: index = index [0] rad = index.Rad () status, text = själv.modell.Todos [rad] själv.modell.Todos [rad] = (sant, text) # .Datachanged tar topp till vänster och längst ner till höger, som är lika # för ett enda urval. själv.modell.dathållad.Emit (index, index) # rensa valet (eftersom det inte är långt giltigt). själv.todview.ClarSelection ()
Detta använder samma indexering som för radering, men den här gången hämtar vi objektet från modellen .Todoslista och ersätt sedan statusen med True .
Vi måste göra detta hämtning och ersättning, eftersom våra data lagras som Python Tuples som inte kan modifieras.
Nyckeln annorlunda här vs. Standard QT -widgetar är att vi gör förändring direkt till våra data och enkelt behöver meddela QT som ändrar haasurd – Uppdatering av widgetstaten hanteras automatiskt.
Använda Qt.Dekorationrol
Om du kör applikationen nu bör du upptäcka att att lägga till och ta bort båda arbetena, men när du slutför artiklar fungerar det ingen indikation på det i vyn. Vi måste uppdatera vår modell för att ge vyn en indikator att visas när ett objekt är klart. Den uppdaterade modellen visas nedan.
tick = qtgui.Qimage ('Tick.png ') klass TODODODEL (Qtcore.QabstractListModel): def __init __ (själv, *args, todos = ingen, ** kwargs): super (todomodel, self).__init __ (*args, ** kwargs) själv.Todos = Todos eller [] def data (själv, index, roll): om roll == qt.DisplayRole: _, text = själv.TODOS [index.Rad ()] returnera text om roll == qt.DekorationsRole: Status, _ = själv.TODOS [index.Rad ()] om status: return tick def rowcount (self, index): return len (self.todos)
Använde en fästingikon.PNG för att ange kompletta objekt, som vi laddar in i ett Qimage -objekt som heter Tick . I modellen implementerade vi en hanterare för QT.DekorationsRole som returnerar fästikonen för rader som är status är sant (för komplett).
Ikonen jag använder är hämtad från fuga som ställts in av P.yusukekamiyaman
Intostad av en i -ikon kan du också återvända till färg, e.g. Qtgui.Qcolor (‘grön’) som kommer att dras som solid fyrkantig.
Kör appen bör du nu kunna markera objekt som komplett.

Todos märkt komplett
En kvarvarande datalagra
Vår Todo-app fungerar snyggt, men den har en dödlig brist-det glömmer dina Todos så snart du stänger applikationen medan du tror att du inte har något att göra när du gör kanske för att bidra till kortvariga känslor av Zen, långvarig är det förmodligen en dålig idé.
Lösningen är att implementera en del utflykt av Persist Data Store. Det enklaste tillvägagångssättet är en enkel filbutik, där vi laddar objekt från en JSON- eller Pickle -fil vid start och skriv tillbaka på förändring.
För att göra detta definierar vi två nya metoder på vår hand . Dessa lastdata från en JSON -filnamndata.JSON (om det finns, ignorerar felet om det inte gör det).modell.Todos och skriv det nuvarande jaget.modell.Todos till samma fil, respektive.
Def Load (self): Prov: Med Open ('Data.json ',' r ') som f: själv.modell.Todos = JSON.Load (f) Undantag Undantag: Pass Def Save (Self): Med Open ('Data.json ',' w ') som f: data = json.Dumpning.modell.TODOS, F)
För att fortsätta ändringarna av de uppgifter vi behöver för att lägga till .Spara () hanterare till slutet av någon metod som modifierar data och .Ladda () hanterare till __init__ -blocket efter att modellen har skapat.
Den slutliga koden ser ut så här –
Importera sys import JSON från Pyqt5 Importera Qtcore, Qtgui, Qtwidgets, UIC från Pyqt5.Qtcore import qt_creator_file = "mainwindow.ui "ui_mainwindow, qtBaseclass = uic.LoadUdUsePeyP (qt_creator_file) tick = qtgui.Qimage ('Tick.png ') klass TODODODEL (Qtcore.QabstractListModel): def __init __ (själv, *args, todos = ingen, ** kwargs): super (todomodel, self).__init __ (*args, ** kwargs) själv.Todos = Todos eller [] def data (själv, index, roll): om roll == qt.DisplayRole: _, text = själv.TODOS [index.Rad ()] returnera text om roll == qt.DekorationsRole: Status, _ = själv.TODOS [index.Rad ()] om status: return tick def rowcount (self, index): return len (self.Todos) klass MainWindow (Qtwidgets.Qmainwindow, ui_mainwindow): def __init __ (self): super (mainwindow, self).__I sig själv.Setupui (själv) själv.Modell = todomodel () själv.Load () själv.todview.Setmodel (själv.Modell) själv.addButton.Tryck.Connect (self.Lägg till) själv.deleteButton.Tryck.Connect (self.Radera) själv.Komplettbutton.Tryck.Connect (self.Komplett) def add (self): "" "Lägg till ett objekt i vår TODO -lista, få texten från QLineEdit .TODOEDIT och där rensar det. "" "Text = själv.todit.Text () Om text: # Lägg inte till tomma strängar. # Komma åt listan via modellen. själv.modell.toddos.Bifoga ((falsk, text)) # trigger uppdatering. själv.modell.skiktad.Emit () # töm ingången själv.todit.SetText ("") själv.Spara () def delete (self): index = self.todview.SelectedDindexes () Om Index: # Index är en lista över en enda artikel i enstaka selektioner. Index = index [0] # ta bort objektet och uppdatera. Del själv.modell.TODOS [index.Rad ()] själv.modell.skiktad.Emit () # rensa valet (eftersom det inte är långt giltigt). själv.todview.ClarSelection () self.Spara () def komplett (self): index = self.todview.SelectredIndexes () om index: index = index [0] rad = index.Rad () status, text = själv.modell.Todos [rad] själv.modell.Todos [rad] = (sant, text) # .Datachanged tar topp till vänster och längst ner till höger, som är lika # för ett enda urval. själv.modell.dathållad.Emit (index, index) # rensa valet (eftersom det inte är långt giltigt). själv.todview.ClarSelection () self.Spara () def load (self): prova: med öppen ('data.db ',' r ') som f: själv.modell.Todos = JSON.Load (f) Undantag Undantag: Pass Def Save (Self): Med Open ('Data.db ',' w ') som f: data = json.Dumpning.modell.Todos, f) app = qtwidgets.QApplication (SYS.Argv) fönster = mainwindow () fönster.Visa () app.Exec_ ()
Om uppgifterna i din applikation har potential att bli stora eller mer komplexa, kan du prefe att använda en faktisk databas för att lagra den. I detta fall kommer modellen att packa in gränssnittet till databasen och fråga det direkt för data att visa. Jag täcker hur man gör detta i en kommande handledning.
För ett annat intressant exempel på en QListView se detta exempel media Player Application. Den använder QT Building QMediaPlayList som datastore, med innehållet display till en qlistview .
Om BCR.CX:
Bcr.CX är en brasiliansk teknikstart, specialiserad på både både affärs outsourcingprocesser (BPO) och affärsmiljö outsourcing (BEO), främst fokuserad på efterfrågan, kundupplevelse, kommunikation, användarstöd och tillfredsställelse.
Beskrivning:
TODO-appen utvecklades som ett snabbt, säkert och användarvänligt sätt att lagra agentens anteckningar under arbetsdagarna.
Kunna skapa och hantera dina egna uppgifter, baserat på varje enskild biljett eller kund.
Skapa spår och anpassa ditt arbetsflöde
Produktivitetsförbättring! Med hjälp av TODO -appen kan du skapa anpassade arbetsflöden för att standardisera repeterande processer. Försök nu och börja kontrollera dina framsteg, som dina Todos och Dones.
Resurser:
- Skapa uppgifter för varje biljett
- Framstegsfält för att följa upp leveransen
- Skapa standardiserade arbetsflöden för att förbättra produktiviteten.
- Hantera din uppgiftslista för att hålla den uppe med din dagliga rutin.
- Stapla både TODO och Zendesk Sunshine för att få full åtkomst över appfunktionerna
- Förbättra produktiviteten genom att skapa eller redigera uppgifter automatiseringar och spara dina personliga förinställningar.
