Qt - jak rozwiązać problem, że po wciśnięciu klawisza BACKSPACE program spełnia warunek...

0

Prawie jak w temacie ale rozwinę jaki jest problem

Na poniższym screenie mam taką grupę widgetów - QCheckBox który po zaznaczeniu ma za zadanie aktywować QLineEdit

screenshot-20210104135052.png

Po aktywacji QLineEdit kontrolka jest gotowa do przyjmowania tekstu i teraz najważniejsze. Kontrolka CELOWO ustawiona jest do przyjmowania konkretnych znaków które nie są literami ani liczbami - czyli może przyjmować JEDEN ze znaków -> , ? / : ; " ' ~ `` ! @ # $ % ^ & * ( ) - _ = + [ ] { } spacja

mam napisaną funkcję która sprawdza wprowadzane znaki i jej zadaniem jest przyjąć właściwy znak, a jeżeli znak jest błędny, to wywala komunikat. Funkcja wygląda jak niżej

void myWindowOptionOpenCSV::getTextOnQlineEdit(const QString &txt)
{
    regex.setPattern(QString("[^A-Za-z0-9\\p{L}.]"));
    match = regex.match(txt);
    if(match.hasMatch()){
        qDebug()<< "Dobrze" << txt << match.capturedTexts();
    }
    else{
        QMessageBox::information(this,QString(tr("Ważna informacja")),
                                 QString(tr("Dopuszczalny jest jeden znak z podanych poniżej\n, ? / : ; \" \' ~ ` ! @ # $ % ^ & * ( ) - _ = + [ ] { } spacja")),QMessageBox::Ok);
        qDebug()<< "Podaj wymagane znaki" << txt;
    }
}

i teraz pytanie jest takie.
W jaki sposób w tej funkcji napisać warunek tak, że jak wcisnę klawisz BACKSPACE to ta funkcja NIE MOŻE ZWRACAĆ warunku z okienkiem QMessageBox ?

Bo w sumie kasowanie znaków jest kasowaniem źle wprowadzonego znaku

2

To mi wygląda na problem, który jest już rozwiązany:

Zwróć uwagę, że okienko wyskakujące w trakcie pisania (tak jak to zrobiłeś), będzie straszliwe uciążliwe dla użytkownika.

0

@MarekR22:
Przetestowałem, fajne, sprawdza się mam dwie uwagi

ale najpierw pokażę kod jak to wygląda aby łatwiej było ocenić gdzie tkwi błąd

myWindowOptionOpenCSV::myWindowOptionOpenCSV(QWidget *parent) : QWidget(parent)
{
    QObject::connect(lineEdOther, &QLineEdit::textEdited, this, &myWindowOptionOpenCSV::getTextOnQlineEdit);
}

//validator
void myWindowOptionOpenCSV::getTextOnQlineEdit(const QString &txt)
{
    regex.setPattern(QString("[^A-Za-z0-9\\p{L}.]"));
    match = regex.match(txt);

    QValidator *validator = new QRegularExpressionValidator(regex, this);

    if(match.hasMatch()){
        lineEdOther->setValidator(validator);
        qDebug()<< "Dobrze" << txt << match.capturedTexts();
    }
}

UWAGA numer

  1. Do slota który sprawdza zawartość wpisanego tekstu, znakiem zastrzeżonym również jest znak kropki, ponieważ kropka używana jest do liczb zmiennoprzecinkowych np 11.5. Przy PIERWSZYM uruchomieniu programu gdy wybiorę WPISYWANIE pierwszego znaku i "tarfia" na kropkę, validator kropkę "wpuszcza" i pojawia się w kontrolce. O dziwo z całego zestawu znaków zastrzeżonych za pierwszym razem wpuszcza TYLKO kropkę. Natomiast gdy w tym samym czasie wpiszę jakiś inny znak, który jest DOZWOLONY skasuję go i następnie wpiszę kropkę, to kropka już się nie pojawia. Gdzie może być problem ? Wyrażenie regularne jest prawidłowe - testowałem do oporu

W moim pierwszym kodzie kropka nie przechodziła - w ogóle nie przechodzą znaki niedozwolone...

  1. Przy zastosowaniu validatora jest brak możliwości wyświetlenia okienka z informacją "o dozwolonych znakach" które można wprowadzić - obecnie użytkownik wali na ślepo w nadziei, że uda mu się wprowadzić jakiś znak - przypomina mi to użytkownika który pierwszy raz odpalił edytor Vi :D

więc jak można zrobić aby to okienko z informacją o poprawnych znakach pokazywało się ?

0

Ad.1
IMHO może Ci po prostu nie działać regex. Napisz testy dla walidatora. Nie jestem pewien czy QT wspiera składnię \p{L}, imho niekoniecznie. Testy i dokumentacja Twoim przyjacielem. Mnie się teraz nie chce sprawdzać ;) Rozumiem, że chcesz wyciąć wszystko poza znakami specjalnymi, spacją i kropką? Jeśli tak, to [^0-9\p{L}.] samo z siebie powinno być wystarczające. EDIT @tajny_agent ma rację. Ale nadal imho przekombinowałeś samego regexa (tak na marginesie).
Ad. 2
Nie da się, bo Ci walidator blokuje te znaki po coś. Zrób tooltipa, pokaż coś na pasku zadań albo wyświetl labela w momencie aktywacji pola tekstowego albo coś w tym kierunku. Tak czy siak: nie, nie pokazuj tego okna, bo użytkownika trafi.

1

@zkubinski:
Pierwsze sprawdzenie robisz "gołym" regex. Dopiero jak hasMatch() jest prawdziwe to ustawiasz walidator dla kontrolki.

Obecnie z każdą zmianą tekstu tworzysz nową instancję walidatora i w kółko ustawiasz ten sam regex. To nie ma sensu.
Powinieneś to zrobić raz, najlepiej w konstruktorze

auto regex = /* init */;
auto validator = new QRegexExpressionValidator(regex, this);
m_lineEdit = new QLineEdit(this);
m_LineEdit->setValidator(validator);

1 użytkowników online, w tym zalogowanych: 0, gości: 1