TODO pe Mac App Store, folosind arhitectura PYQT5 ModelView pentru a construi o aplicație simplă TODO

Arhitectura ModelView QT S MVC Interfață pentru afișarea datelor în vizualizări

Aplicația care rulează este prezentată mai jos.

TODO 4+

De câțiva ani am folosit această aplicație pe iPad, iPhone și MacBookPro. Dacă continuă să funcționeze perfect pe iOS, se pare că nu a urmat pe deplin evoluția macOS.
Fără probleme pentru instalarea acesteia. Dar nu mai este posibil să se sincronizeze cu Toodledo pe macOS, în timp ce continuă să fie posibil pe iOS: aceiași identificatori nu sunt recunoscuți.
Prin urmare, devine inutil pentru mine … iar asistența lui Appigo nu pare să se grăbească să ofere un răspuns la cererea mea. Este întotdeauna neplăcut să rețineți că conceptul de client pierde puțin mai mult din valoarea sa în fiecare zi.

Pisa d

De la această actualizare, mi -am pierdut toate listele în numărul de 12 și cu care lucrez zilnic într -o manieră profesională. Gestionez în permanență aproximativ 200 de locuri, această actualizare a pus la sol luni de calvar ! Toate sarcinile organizate în listă s -au găsit grupate într -o singură listă globală. Cu siguranță nu este această eroare care mă va face să trec la versiunea spunând profesionistul acestui software altfel excelent. Nu voi fi niciodată captiv. Rămâne doar pentru mine să aștept răspunsul suportului contactat în această seară prin e -mail sau apoi să găsesc vechea versiune a acestui software magnific. Sper într -adevăr că este un beug de tinerețe al noii versiuni și nu o strategie de forțat să migreze la versiunea pro plătită pentru a găsi funcționalități deja achiziționate cu versiunea anterioară. Pentru informații sincronizarea mea se face cu Dropbox

Surlepoint, 13/12/2011

Sincrolul este acum nichel

Am apucat înainte de sincronizarea care a fost lentă, a mers prost etc. Dar acum cu iCloud, mi se potrivește perfect.

Câteva îmbunătățiri posibile: mai multe setări de afișare.
– pentru a afișa doar ceea ce utilizează utilizatorul. De exemplu, nu folosesc contexte sau etichete (în orice caz nu încă) și aș dori să nu mai afișez aceste opțiuni care „poluează” todo -ul meu. Aș dori să am doar „data / prioritatea / lista / tipul” pentru notele mele de zi cu zi și pentru a face clic dreapta pentru opțiunile pe care le folosesc rar
– În schimb, aș dori un afișaj PLSU simplu decât un meniu de cădere pentru a alege data, prioritatea, lista, … dacă am doar trei liste, atunci trei butoane ar fi suficiente pentru a fi afișate și aș putea alege lista mea Cu un singur clic în loc să faceți clic pe meniul Drop -down, găsiți numele și faceți clic pe el. (Ditto pentru prioritate, mai ales că trecem de la un desen foarte vizual pe lista Todo la o alegere a numelui în opțiunile care nu sunt foarte naturale.

Acestea sunt detalii despre ergonomie. Îmi place simplitatea și eficiența todo -ului, așa că mi -ar plăcea că poate fi și mai configurabil pentru a fi și mai simplu.

Aplicație de confidențialitate

Dezvoltatorul, Appigo, nu a oferit detalii despre practicile sale private și gestionarea datelor către Apple. Pentru mai multe informații, consultați Politica de confidențialitate a dezvoltării.

Arhitectura ModelView
Interfața asemănătoare MVC a QT pentru afișarea datelor în vizualizări

Pe măsură ce începeți să construiți aplicații mai complexe cu PYQT5, veți putea întâlni widget -uri în sincronizare cu datele dvs. Date stocate în widget -uri (E.g. Un simplu QlistWidget) nu este ușor disponibil pentru a manipula de la Python – Modificările necesită să obțineți un articol, să obțineți datele, apoi să le setați înapoi. Soluția implicită în acest sens este de a păstra o reprezentare externă a datelor în Python, iar apoi EITH Duplicate actualizări atât la date, cât și la widget, sau pur și simplu rescrieți wihole widget din date. Acest lucru poate deveni urât rapid și duce la o mulțime de cazanuri doar pentru a juca datele.

Din fericire, QT are o soluție pentru acest lucru – ModelViews. ModelViews este o alternativă puternică la widget -urile de afișare standard, care utilizează o interfață model obișnuită pentru a interacționa cu surse de date – de la structuri de date simple la baze de date externe. Acest lucru izolează datele dvs., permițându -le să fie păstrată în orice structură care vă place, în timp ce vederea are grijă de prezentare și actualizări.

Acest tutorial introduce aspectele cheie ale Arhitecturii ModelView de la QT și îl folosește pentru a construi o aplicație simplă pentru desktop TODO în PYQT5.

Controler de vizualizare model

Model – vezi – Controler (MVC) este o utilizare a modelului arhitectural pentru interfețele de utilizator pentru dezvoltare care divizează o aplicație în trei părți interconectate. Aceasta separă reprezentarea internă a datelor de modul în care informațiile sunt prezentate și acceptă de la utilizator.

MVC Design Pattenn FETS trei componente majore –

  • Model Deține structura de date cu care lucrează aplicația.
  • Vedere este orice reprezentare a informațiilor, așa cum se arată utilizatorului, unde grafic sau tabel. Sunt permise mai multe vizualizări ale aceluiași model de date.
  • Control Acceptă introducerea de la utilizator, transformându -l în comenzi pentru model sau vizualizare.

Qt aterizează distincția dintre vizualizare și controler devine puțin întunecată. QT acceptă evenimente de intrare de la utilizator (prin intermediul sistemului de operare) și le delegează pe widget -uri (controler) pentru a gestiona. Cu toate acestea, widget -urile gestionează și prezentarea stării actuale pentru utilizator, punându -le în mod clar în vedere. În loc să agonizeze unde să tragă linia, în QT-S-SPAIK, vizualizarea și controlerul sunt contopite în top a unui model/vizualizare arhitectură numită „Vizualizare model” de simplitate.

Important este distincția dintre date și Cum este prezentat este păstrat.

Vizualizarea modelului

Modelul acționează ca interfața dintre depozitul de date și ViewController. Modelul deține datele (sau o referire la acestea) și prezintă aceste date printr -o API standardizată, care vizualizează apoi consumă și prezintă utilizatorului. Vizualizări multiple pot partaja aceleași date, prezentându -le în moduri complet diferite.

Puteți utiliza orice „magazin de date” pentru modelul dvs., inclus de exemplu o listă sau un dicționar standard Python sau o bază de date (prin E.g. Sqlalchemy) – Este în mod dreptul de la tine.

Cele două părți sunt în esență responsabile de –

  1. Ceai model Stochează datele sau o referință la acestea și returnează individual sau intervale de înregistrări și metadate asociate sau afişa instrucțiuni.
  2. Ceai vedere Solicită date de la model și afișează ceea ce este returnat pe widget.

În documentație există o discuție aprofundată a arhitecturii QT.

Ghidul complet pentru ambalarea aplicațiilor Python GUI cu Pyinstaller.

Ambalare aplicații Python cu pyinstaller

[[reducere.Reducere_pc]]]% reducere pentru următorul [reducere.durată]] [reducere.Descriere]] cu codul [reducere.cupon_code]]

Paritate de putere de cumpărare

Dezvoltatorii din [[țară]] primesc [[reducere.reducere_pc]]] pe toate cărțile și cursurile cu cod [reducere.cupon_code]]

O vizualizare simplă a modelului – o listă TODO

Pentru a demonstra modul de utilizare a modelelor în practică, vom pune la cale o implementare foarte simplă a unei liste de todo desktop. Acest lucru va consta dintr -un QListView pentru lista de articole, un QlineEdit pentru a introduce articole noi și un set de butoane pentru a adăuga, șterge sau marca articolele așa cum s -a terminat.

UI

UI simplă a fost o ieșire urâtă QT Creator și salvată ca MainWindow.UI . Ceai .Fișierul UI și toate celelalte părți pot fi descărcate mai jos.

Proiectarea unei aplicații simple TODO în QT Creator

Proiectarea unei aplicații simple TODO în QT Creator

Aplicația care rulează este prezentată mai jos.

GUI -ul care rulează (nimic nu funcționează încă)

GUI -ul care rulează (nimic nu funcționează încă)

Widget -urile disponibile în interfața pe care am dat -o ID -urile afișate în tabelul de mai jos.

Objeuch Drăguț Descriere
TodView QlistView Lista tod -urilor actuale
Tododit Qlineedit Intrarea textului pentru crearea unui nou element TODO
AddButton QpushButton Creați noul TODO, adăugându -l la lista TODOS
deleteButton QpushButton Ștergeți curentul selectat actual, eliminându -l din lista TODOS
Complet buton QpushButton Marcați curentul selectat, așa cum s -a făcut

Vom folosi acești identificatori pentru a conecta logica aplicației mai târziu.

Modelul

Definim modelul nostru personalizat subclasând de la implementare, permițându -ne să ne concentrăm pe piesele unice pentru modelul nostru. QT oferă o serie de baze de model diferite, inclusiv liste, copaci și tabele (ideale pentru foi de calcul).

Pentru acest exemplu, afișăm rezultatul la un QListView . Modelul de bază care se potrivește pentru aceasta este QabstractListModel . Definiția conturului pentru modelul nostru este prezentată mai jos.

Clasa ToDomodel (Qtcore.QabstractlistModel): def __init __ (self, *args, todos = none, ** kwargs): super (todomedel, self).__init __ (*args, ** kwargs) self.TODOS = TODOS sau [] DEF DATE (SELL, INDEX, ROL): IF ROL == QT.DisplayRole: # Vezi mai jos pentru structura de date. Stare, text = self.Todos [Index.Rând ()] # returnează doar textul TODO. Return text def rowcount (self, index): return len (self.Todos) 

Ceai .Variabila TODOS este depozitul nostru de date și cele două metode RowCount () și date () sunt metode de model standard, trebuie pentru un model de listă. Vom trece prin acestea pe rând.

.Lista TODOS

Depozitul de date pentru modelul nostru este .Todos, o listă simplă de piton în care vom stoca un tuple de valori în format [(bool, str), (bool, str), (bool, str)] unde boolul este cel prin urmare starea unei intrări date, iar str este textul todo -ului.

Inițializăm sinele.Todo la o listă goală de la pornire, cu excepția cazului în care o listă este transmisă prin intermediul argumentului de cuvinte cheie TODOS.

de sine.Todos = Todos sau [] va seta self.Todos la valoarea TODOS furnizată dacă este truty (i.e. Orice altceva decât o listă goală, falsa booleană sau niciuna valoarea implicită), altfel va fi setată pe lista goală [] .

Pentru a crea o poziție a acestui model, putem simplifica –

Model = toDomodel () # Creați o listă goală TODO 

Sau pentru a trece într -o listă existentă –

todos = [(false, 'un element'), (fals, 'un alt element')] model = todomodel (todos) 

.RowCount ()

Ceai .Metoda RowCount () este apelată prin vizualizare pentru a obține numărul de rânduri din datele curente. Acest lucru este necesar pentru vizualizarea până acum indicele maxim pe care îl poate reface depozitul de date (rândul numărului-1). Vânzare Folosim o listă Python ca magazin de date, valoarea de returnare pentru aceasta este pur și simplu len () din listă.

.Date ()

Acesta este nucleul modelului dvs., care gestionează cererile de date din vizualizare și returnează rezultatul corespunzător. Primește doi parametri index și rol.

Indexul este poziția/coordonatele datelor pe care le solicită viziunea, accesibilă prin două metode .Rând () și .coloană () care dau poziția în fiecare dimensiune.

Pentru QlistView, coloana este întotdeauna 0 și poate fi ignorată, dar va trebui să utilizați acest lucru pentru datele 2D într -o vizualizare a foii de calcul.

Rolul este un steag care indică drăguț de date pe care le solicită vizualizarea. Acest lucru se datorează faptului că .Metoda Data () are de fapt mai multă responsabilitate decât doar datele de bază. De asemenea, gestionează solicitările de informații despre stil, scule, bare de stare etc. – Bazal orice ar putea fi informat de datele în sine.

Denumirea Qt.DisplayRole este un pic ciudat, dar acest lucru indică faptul că vedere ne cere „vă rog să -mi dați date pentru afișare”. Există și altele roluri Pe care datele le pot primi pentru solicitări de coafură sau pentru a solicita date în format „edit-gata”.

Rol Valoare Descriere
Qt.Afişa 0 Datele cheie care trebuie redate sub formă de text. (QString)
Qt.DecorationRol 1 Datele care vor fi redate ca decor sub forma unei pictograme. (QColor, QiCon sau QpixMap)
Qt.Editorial 2 Datele într -o urmărire formală pentru editare într -un editor. (QString)
Qt.Tooltiprole 3 Datele afișate în instrumentul de instrument al articolului. (QString)
Qt.Statustiprole 4 Datele afișate în bara de stare. (QString)
Qt.Whats Thisrole 5 Datele afișate pentru articol în „Ce este acest lucru?” Modă. (QString)
Qt.Sizehintrol 13 Sugestia de mărime pentru elementul care va fi furnizat vizualizărilor. (Qsize)

Pentru o listă completă de disponibilă roluri pe care îl puteți primi, consultați documentația qt itmdatarole. Lista noastră TODO va folosi doar QT.DisplayRole și Qt.DecorationRol .

Implementare de bază

Mai jos este aplicația de bază necesară pentru încărcarea UI și afișarea acesteia. Vom adăuga codul modelului și logica aplicației la această bază.

Import sys din Pyqt5 Import Qtcore, QtGui, Qtwidgets, UIC de la PYQT5.Qtcore import qt_creator_file = "mainwindow.UI "UI_MAINWINDOW, QTBASECLASS = UIC.Loaduduype (QT_Creator_File) Class ToDomodel (QTCORE.QabstractlistModel): def __init __ (self, *args, todos = none, ** kwargs): super (todomedel, self).__init __ (*args, ** kwargs) self.TODOS = TODOS sau [] DEF DATE (SELL, INDEX, ROL): IF ROL == QT.DisplayRole: Status, text = self.Todos [Index.Rând ()] return text def rowcount (self, index): return len (self.TODOS) clasa MainWindow (Qtwidgets.Qmainwindow, ui_mainwindow): def __init __ (self): qtwidgets.Qumainwindow.__init __ (self) ui_mainwindow.__init __ (sine).Setupui (self) self.Model = todomodel () self.TodView.SetModel (Self.Model) aplicație = qtwidgets.QApplication (sys.Argv) fereastră = fereastră mainWindow ().Aplicație Show ().Exec_ () 

Ne definim todomedelul ca înainte și inițializăm obiectul MainWindow. În __init__ pentru MainWindow, creăm o instanță a modelului nostru TODO și stabilim acest model pe TODO_VIEW . Salvați acest fișier ca TODO.Py și rulează -l cu –

Python3 Todo.ritm 

Deși încă nu există multe de văzut, QlistView și modelul nostru funcționează de fapt – dacă adăugați unele date implicite, le veți vedea că apar în listă.

de sine.model = toDomodel (todos = [(fals, 'primul meu todo')]))) 

QListView care arată elementul TODO codat dur

QListView care arată elementul TODO codat dur

Puteți continua să adăugați elemente manual ca acesta și acestea vor apărea în ordine în QlistView . În continuare, vom face posibilă adăugarea ITMS din aplicație.

Mai întâi creați o nouă metodă pe MainWindow numit Adăugare . Acesta este apelul nostru care va avea grijă să adauge textul curent de la intrare ca un nou Todo. Conectați această metodă la AddButton.Semnal apăsat la sfârșitul blocului __init__.

Clasa MainWindow (Qtwidgets.Qmainwindow, ui_mainwindow): def __init __ (self): qtwidgets.Qumainwindow.__init __ (self) ui_mainwindow.__init __ (sine).Setupui (self) self.Model = todomodel () self.TodView.SetModel (Self.Model) # Conectați butonul. de sine.AddButton.presa.Conectați -vă (Self.Adăugare) def Adăugați (self): "" Adăugați un element la lista noastră de todo, obținând textul de la QlineEdit .Todoedit și acolo ștergeți -l. "" "text = self.Tododit.Text () dacă text: # nu adăugați șiruri goale. # Accesați lista prin intermediul modelului. de sine.model.Todos.Anexă ((falsă, text)) # Trigger Refresh. de sine.model.Layoutchanged.Emit () # goliți sediul de intrare.Tododit.SetText ("") 

În bloc Adăugare observați linia de sine.model.Layoutchanged.Emit () . Aici emitem un semnal de model .layoutchanged pentru a anunța viziunea că formă a datelor a fost modificată. Acest lucru declanșează o actualizare a entității vizualizării. Dacă omiteți această linie, TODO va fi adăugat în continuare, dar QlistView nu se va actualiza.

Dacă doar datele sunt modificate, dar numărul de rânduri/coloane nu sunt afectate, puteți utiliza .Semnal de date de date () în schimb. Acest lucru definește, de asemenea, o regiune modificată în date folosind o închiriere de sus și partea de jos din dreapta jos pentru a evita redarea întregului vizualizare a vizualizării.

Agățând celelalte acțiuni

Acum putem conecta restul semnalelor butonului și adăugăm ajutor pentru performanță șterge și complet operații. Adăugăm semnalele butonului la blocul __init__ ca înainte.

 de sine.AddButton.presa.Conectați -vă (Self.Adaugă) sine.deleteButton.presa.Conectați -vă (Self.Ștergeți) Sinele.Complet buton.presa.Conectați -vă (Self.Complet) 

Apoi definiți o nouă metodă de ștergere după cum urmează –

 Def ștergere (self): indexuri = self.TodView.SelectedDindexes () IF indexes: # indexuri este o listă a unui singur element într-o singură selecție. Index = indexuri [0] # Eliminați elementul și actualizați. Del sine.model.Todos [Index.Rând ()] self.model.Layoutchanged.Emit () # Ștergeți selecția (deoarece nu este valabilă de mult timp). de sine.TodView.ClarSelection () 

Ne folosim de sine.TodView.selectatdindexes pentru a obține indexurile (de fapt o listă a unui singur articol, așa cum noi în modul unic selecție) și apoi .Rând () ca index în lista noastră de ToDO -uri pe modelul nostru. Ștergem elementul indexat folosind Operatorul Del al Python, apoi declanșăm un semnal de schimb de layout, deoarece forma datelor a fost modificată.

În mod fin, ștergem selecția activă, deoarece articolul la care se referă acum, poate fi în afara limitelor (dacă ați selectat ultimul articol).

Ați putea încerca să faceți acest Smartter și să selectați în schimb ultimul element din listă

Metoda completă îi place așa –

 Def complet (self): indexuri = self.TodView.SelectredIndexes () dacă indexuri: index = indexuri [0] rând = index.Stare rând (), text = self.model.Todos [rând] self.model.Todos [rând] = (adevărat, text) # .DataChanged ia în stânga sus și în partea dreaptă jos, care sunt egale # pentru o singură selecție. de sine.model.Datachanged.Emit (index, index) # Ștergeți selecția (deoarece nu este valabilă de mult timp). de sine.TodView.ClarSelection () 

Aceasta folosește aceeași indexare ca pentru ștergere, dar de data aceasta preluăm articolul din model .Lista TODOS și apoi înlocuiți starea cu True .

Trebuie să facem acest preluare și înlocuire, deoarece datele noastre sunt stocate ca tupluri Python care nu pot fi modificate.

Cheia diferită aici vs. Widget -urile QT standard sunt că facem modificări direct la datele noastre și trebuie să notificăm simplu QT care modifică Haasurd – Actualizarea stării widgetului este gestionată automat.

Folosind Qt.DecorationRol

Dacă rulați aplicația acum, ar trebui să aflați că adăugarea și ștergerea ambelor lucrări, dar, în timp ce completați articolele funcționează, nu există nicio indicație despre aceasta. Trebuie să ne actualizăm modelul pentru a oferi vizualizarea cu un indicator de afișat atunci când un articol este complet. Modelul actualizat este prezentat mai jos.

Tick ​​= qtgui.Qimage ('bifați.PNG ') CLASA TODODODEL (QTCORE.QabstractlistModel): def __init __ (self, *args, todos = none, ** kwargs): super (todomedel, self).__init __ (*args, ** kwargs) self.TODOS = TODOS sau [] DEF DATE (SELL, INDEX, ROL): IF ROL == QT.DisplayRole: _, text = self.Todos [Index.Rând ()] return text dacă rolul == qt.DecorationRole: statut, _ = self.Todos [Index.Rând ()] dacă starea: return tick def rowcount (self, index): return len (self.Todos) 

Folosesc o pictogramă de bifare căpușă.PNG pentru a indica articole complete, pe care le încărcăm într -un obiect QImage numit Tick . În model am implemetat un manipulator pentru QT.DecorationRole care returnează pictograma Tick pentru rândurile care starea este adevărată (pentru complet).

Pictograma pe care o folosesc este preluată din setul de fugă de P.yusukekamiyamane

Intostad al unei pictograme I, puteți reveni și la culoare, E.g. QtGui.QColor („verde”) care va fi tras ca pătrat solid.

Rularea aplicației, acum ar trebui să puteți marca articolele la fel de complete.

Todos marcat complet

Todos marcat complet

Un depozit de date persist

Aplicația noastră TODO funcționează frumos, dar are un defect fatal-uită-ți copiii de îndată ce închideți aplicația, în timp ce credeți că nu aveți nimic de făcut atunci când puteți contribui la sentimente pe termen scurt de zen, pe termen lung este probabil un Idee rea.

Soluția este de a implementa unele ieșiri de stocare de date persistente. Cea mai simplă abordare este un depozit de fișiere simplu, unde încărcăm articole dintr -un fișier JSON sau murat la pornire și scriem înapoi la schimbare.

Pentru a face acest lucru, definim două noi metode pe mâna noastră . Aceste date de încărcare dintr -un nume de nume al fișierului JSON.Json (dacă există, ignorând eroarea dacă nu).model.TODOS și scrieți -vă actualul.model.Todos a ieșit la același fișier, respectiv.

 Def Load (Self): Încercați: cu Open ('Date.json ',' r ') ca f: self.model.TODOS = JSON.Încărcare (f) Excepție Excepție: PASS DEF SAVE (SELF): cu Open ('Date.json ',' w ') ca f: date = json.Dump (sine.model.Todos, f) 

Pentru a persista modificările la datele, trebuie să adăugăm .Salvați () gestionarea la sfârșitul oricărei metode care modifică datele și .Load () Handler la blocul __init__ după ce modelul a fost creat.

Codul final arată astfel –

Import sys import JSON de la Pyqt5 Import Qtcore, QtGui, Qtwidgets, UIC de la PYQT5.Qtcore import qt_creator_file = "mainwindow.UI "UI_MAINWINDOW, QTBASECLASS = UIC.LOADUDUSEYPE (QT_CREATOR_FILE) Tick = qtGui.Qimage ('bifați.PNG ') CLASA TODODODEL (QTCORE.QabstractlistModel): def __init __ (self, *args, todos = none, ** kwargs): super (todomedel, self).__init __ (*args, ** kwargs) self.TODOS = TODOS sau [] DEF DATE (SELL, INDEX, ROL): IF ROL == QT.DisplayRole: _, text = self.Todos [Index.Rând ()] return text dacă rolul == qt.DecorationRole: statut, _ = self.Todos [Index.Rând ()] dacă starea: return tick def rowcount (self, index): return len (self.TODOS) clasa MainWindow (Qtwidgets.Qmainwindow, ui_mainwindow): def __init __ (self): super (mainwindow, self).__In sinea lui.Setupui (self) self.Model = todomodel () self.Load () self.TodView.SetModel (Self.Model) Sinele.AddButton.presa.Conectați -vă (Self.Adaugă) sine.deleteButton.presa.Conectați -vă (Self.Ștergeți) Sinele.Complet buton.presa.Conectați -vă (Self.Complet) def Adăugați (self): "" "Adăugați un articol la lista noastră de todo, obținând textul de la QlineEdit .Todoedit și acolo ștergeți -l. "" "text = self.Tododit.Text () dacă text: # nu adăugați șiruri goale. # Accesați lista prin intermediul modelului. de sine.model.Todos.Anexă ((falsă, text)) # Trigger Refresh. de sine.model.Layoutchanged.Emit () # goliți sediul de intrare.Tododit.Settext ("") self.Salvați () def ștergere (self): indexuri = self.TodView.SelectedDindexes () IF indexes: # indexuri este o listă a unui singur element într-o singură selecție. Index = indexuri [0] # Eliminați elementul și actualizați. Del sine.model.Todos [Index.Rând ()] self.model.Layoutchanged.Emit () # Ștergeți selecția (deoarece nu este valabilă de mult timp). de sine.TodView.ClarSelection () Self.Salvați () def Finalizați (Self): indexuri = Self.TodView.SelectredIndexes () dacă indexuri: index = indexuri [0] rând = index.Stare rând (), text = self.model.Todos [rând] self.model.Todos [rând] = (adevărat, text) # .DataChanged ia în stânga sus și în partea dreaptă jos, care sunt egale # pentru o singură selecție. de sine.model.Datachanged.Emit (index, index) # Ștergeți selecția (deoarece nu este valabilă de mult timp). de sine.TodView.ClarSelection () Self.Salvați () DEF LOAD (self): încercați: cu Open ('Date.db ',' r ') ca f: self.model.TODOS = JSON.Încărcare (f) Excepție Excepție: PASS DEF SAVE (SELF): cu Open ('Date.db ',' w ') ca f: date = json.Dump (sine.model.Todos, f) App = qtwidgets.QApplication (sys.Argv) fereastră = fereastră mainWindow ().Aplicație Show ().Exec_ () 

Dacă datele din aplicația dvs. au potențialul de a obține mari sau mai complexe, puteți preferi să utilizați o bază de date reală pentru a o stoca. În acest caz, modelul va înfășura interfața la baza de date și o va interoga direct pentru afișarea datelor. Coperta ll cum să faci asta într -un tutorial viitor.

Pentru un alt exemplu interesant de QlistView, consultați acest exemplu de aplicație media player. Utilizează QT Building QMediapLayList ca depozitare, cu conținutul afișat la un QlistView .

Despre BCR.CX:

BCR.CX este o pornire a tehnologiei braziliene, specializată atât în ​​procesele de externalizare a afacerilor (BPO), cât și în externalizarea mediului de afaceri (BEO), axată în principal pe generarea cererii, experiența clienților, comunicarea, asistența pentru utilizatori și satisfacția.

Descriere:

Aplicația Todo a fost dezvoltată ca un mod rapid, sigur și ușor de utilizat de a stoca notele agentului în timpul zilelor de muncă.

Să vă puteți crea și gestiona propriile sarcini, pe baza fiecărui bilet sau client individual.

Creați trasee și personalizați -vă fluxul de lucru

Productivitatea îmbunătățește! Utilizarea aplicației TODO puteți crea fluxuri de lucru personalizate pentru a standardiza procese repetate. Încercați acum și începeți să vă controlați progresul, în calitate de Todos și Dones.

Resurse:

  1. Creați sarcini pentru fiecare bilet
  2. Progress Bar pentru urmărirea livrării
  3. Creați fluxuri de lucru standardizate pentru a îmbunătăți productivitatea.
  4. Gestionați -vă lista de sarcini, pentru a o ține la curent cu rutina dvs. zilnică.
  1. Stivați atât Todo, cât și Zendesk Sunshine pentru a obține acces complet peste funcțiile aplicației
  2. Îmbunătățirea productivității prin crearea sau editarea automatizării sarcinilor și salvați presetările dvs. personalizate.