2013-02-21 15 views
7

Mój program składa się z wielu QLineEdit w moim QMainWindow. Użytkownik może zmienić tekst w dowolnej wersji QLineEdit. Obecnie mogę wykonać cofnąć przez domyślną implementację dla każdego QLineEdit, gdy wybrana jest odpowiednia QLineEdit. Jednak chcę dodać funkcjonalność, aby po przyciśnięciu moich przycisków undo * odpowiednio zmodyfikowany QLineEdit wykonał cofnij/ponów. tzn. L1, L2 itd. są moje QLineEdit. Następnie użytkownik wykonuje następujące operacje: 1. L2-> tekst dodany ... 5. L5-> tekst dodany ... 9. L3-> tekst usunięty 10. L5-> cofnij (wybierając L5 & następnie "Ctrl + z")Implementacja Cofnij - Ponów funkcjonalność w Qt?

teraz, gdy użytkownik naciśnie Undo/Redo przycisk następująco: 1. Undo -> Gdyby cofnąć Cofnij wykonywanych w kroku 10 2. Undo -> Gdyby cofnąć tekst skasowany w kroku 9 3. Ponów -> Powtórz tekst skasowany w kroku 9 4. Cofnij -> Powinieneś cofnąć operację wykonaną w kroku 8

Obecnie mogę niewyraźnie myśleć o mechanizmie zakładania historii, ale będzie to dość nudne. Więc chciałbym wiedzieć, czy Qt zapewnia mi jakąś wbudowaną funkcjonalność do robienia tego? Dziękuję.

Odpowiedz

9

Qt zapewnia architekturę Undo/Redo.

W zasadzie zaimplementujesz polecenie, wyprowadzone z QUndoCommand, dla każdej akcji, która ma być niedostępna/możliwa do ponownego wykorzystania, a następnie wypchnij ją do QUndoStack. Później komendy można cofnąć i przerobić, wywołując odpowiednie gniazda na QUndoStack.

Należy zauważyć, że po naciśnięciu polecenia na stosie jest ono automatycznie przerabiane na ponownie, oznacza wykonanie po raz pierwszy. Czasem nie jest to to, czego chcesz, ponieważ polecenie mogło już zostać wykonane - musisz wziąć to pod uwagę podczas implementacji poleceń.

+0

Dziękujemy za odpowiedź i dane wejściowe na ten temat! –

3

Jednym ze sposobów wdrożenia tego jest użycie wzoru "Polecenie". Qt udostępnia strukturę cofania, która jest zgodna z tym wzorcem: http://qt-project.org/doc/qt-4.8/tools-undoframework.html

Aby to ułatwić, konieczne może być wprowadzenie pewnych zmian w programie, aby stał się on nieco bardziej MVC (kontroler modelu). Będziesz miał model danych, który reprezentuje zawartość twojego formularza. Sam formularz jest widokiem i kontrolerem - wszelkie zmiany wprowadzane przez użytkownika w edycji linii aktualizowałyby model danych. Model danych wprowadziłby do niego zmiany za pomocą QUndoCommands, które są przekazywane do QUndoStack ze struktury cofania Qt. Gdy stan modelu ulega zmianie (z powodu cofnięcia/ponowienia), interfejs użytkownika zareaguje na zmianę i zostanie zaktualizowany w celu odzwierciedlenia stanu modelu.

+0

Dziękuję za odpowiedź. Zajrzę do tego. Ale nie mogłem w pełni zrozumieć, co rozumiesz przez MVC. Czy to jest koncepcja Qt czy ogólna programująca? –

+1

MVC to ogólna koncepcja programowania. Widok i części kontrolera są tu nieco sprzężone - jak to często bywa w programach GUI. Zasadniczo pomyśl o tym, jak podzielić dane z interfejsu użytkownika. Interfejs użytkownika wyświetla i kontroluje dane. – Pete

+2

Shuld upewnij się również, że Ctrl-Z etc są przekierowywane przez twoje akcje cofania/ponawiania, a nie poprzez QLineEdits, aby poprawnie działały na wszystkich wokach. – Pete

1

Qt ma klasy, aby pomóc w cofnięciu, zobacz QUndoStack. Każdy niemożliwy do wykonania krok powinien zostać zaimplementowany jako podklasa QUndoCommand.

To, co próbujesz osiągnąć, nie jest proste, ponieważ musisz ominąć wewnętrzne stosy cofania swoich numerów QLineEdit. Oto jedna sugestia: posłuchaj sygnału focusChanged od QApplication. Jeśli jedna z edycji linii ma fokus, zapisz zawartość i połącz się z sygnałem QLineEdit::editingFinished().Po otrzymaniu tego polecenia umieść na stosie polecenie ze starym i nowym tekstem. Wada tego podejścia polega na tym, że nie będziesz przechwytywać pośrednich zmian w jednym QLineEdit. Na przykład, jeśli chcesz zapisać 1) użytkownika wybierającego tekst i naciskającego delete, a następnie 2) wpisującego jakiś nowy tekst, jako oddzielne, niezdejmowane kroki, które mogą wymagać rozpoczęcia filtrowania kluczowych zdarzeń, a logika może stać się dość skomplikowana. Ale takie jest ogólne podejście.

+0

Dziękujemy za odpowiedź i również za sugestie. Zajrzę do tego i skontaktuję się z Tobą, jeśli pojawią się jakieś problemy. –