jak w tytule, bo w mediatorze chyba zapędziłem się w kozi róg - teoretycznie on ułatwia komunikację ale jak już chce się "dopieszczać" wizualnie kontrolki, to już tak słabo to widzę. W sumie mam dwa problemy - obecny i przyszły (który w sumie powstaje, bo się kapnąłem przy pisaniu rozwiązania)
- Obecny problem z hermetyzacją polega na tym, że w klasie
MainWindow
pobieram adres tego okna podczas rejestracji do mediatora i wygląda to tak
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), mainWidget{new QWidget(this)}
{
this->setObjectName(QString("MainWindow"));
//dla uproszczenia taki kod
myWindowSettings = new WindowSettings(this);
dataTransferMediator = new Mediator(this); //powstaje okno klasy WindowSettings
dataTransferMediator->registerWindow(myWindowSettings); //pobieram wskaźnik tego okna do mediatora
}
no i tutaj przy pisaniu kodu w mediatorze - (o czym za chwilę) - zastanawiam się czy nieświadomie nie "obszedłem" zasady hermetyzacji klas?
Problem 1 (obecny) - w funkcji registerWindow
pobieram wskaźnik okna klasy WindowSettings
- niby nic niewinnego ale jednak...
void Mediator::registerWindow(QWidget *ptrWidget)
{
bool isRegister = false;
if(ptrWidget){ //prawdopodobnie pierwsze obejście hermetyzacji klas
ptrChildWindowSettings = ptrWidget; //pobieram wskaźnik CAŁEGO OKNA WindowSettings
isRegister = true;
emit registerNewWindow(isRegister);
}
}
w klasie WindowSettings
składowe prywatne wyglądają mniej więcej tak - dla uproszczenia usunąłem kod o którym nie jest mowa - daję w celu głębszego wglądu w sytuację
class WindowSettings : public QDialog
{
Q_OBJECT
private:
//usunięto kod w celach przejrzystości
Page1 *page1;
Page2 *page2;
};
WindowSettings::WindowSettings(QWidget *parent): QDialog{parent}, mainVLayout(new QVBoxLayout(this))
{
this->setObjectName(QString("WindowSettings"));
page1 = new Page1(this); //tworzę Page1 - a za chwilę będę miał do niego dostęp...
page2 = new Page2(this); //tworzę Page2 - a za chwilę będę miał do niego dostęp...
stackedWidget = new QStackedWidget(this);
stackedWidget->addWidget(page1); //![Strona 1]
stackedWidget->addWidget(page2); //![Strona 2]
hLayoutStacked->addWidget(treeStackedWidget);
hLayoutStacked->addWidget(stackedWidget);
}
w funkcji isRegisteredWindow
po pobraniu adresu okna klasy WindowSettings
zaczynam się dobierać do składowych PRYWATNYCH klasy Page1
i Page2
- jak poniżej
Error::RegisterWindowErrors Mediator::isRegisteredWindow(bool isRegister)
{
if(!isRegister){ //niby nic takiego, ALE NIŻEJ...
return Error::RegisterWindowErrors::NotRegistered;
}
window = qobject_cast<WindowSettings*>(ptrChildWindowSettings); //tutaj już chyba zaczynam łamać hermetyzację klas
//bo jawnie pobrałem wskaźnik klasy WindowSettings i NIŻEJ DOBIERAM SIĘ DO SKŁADOWYCH PRYWATNYCH TEJ KLASY!!!
if(!window){
return Error::RegisterWindowErrors::NullPointer;
}
page1 = window->findChild<Page1*>(); //tutaj dobieram się do składowych prywatnych klasy WindowSettings
if(!page1){
return Error::RegisterWindowErrors::MissingPage1;
}
//po dobraniu się do składowych prywatnych klasy WindowSettings, dobrałem się do funkcji publicznych klasy Page1
QObject::connect(page1, &Page1::ipAddress, this, &Mediator::receivedIPAddress); //o tutaj się dobieram
QObject::connect(this, &Mediator::validInputIPaddress, page1, &Page1::setInputFieldValidationColor);
QObject::connect(this, &Mediator::invalidInputIPaddress, page1, &Page1::setInputFieldInvalidColor);
QObject::connect(page1, &Page1::port, this, &Mediator::receivedPort);
// QObject::connect(this, &Mediator::validInputIPaddress, ) //tutaj się kapnąłem, że... czeba dobrać się do składowych prywatnych Page1
page2 = window->findChild<Page2*>(); //tutaj się dobieram do prywatnej składowej klasy WindowSettings
if(!page2){
return Error::RegisterWindowErrors::MissingPage2;
}
return Error::RegisterWindowErrors::RegisterSuccess;
}
no więc co o tym sądzicie? złamałem hermetyzację klas? - powyższe dotyczy obecnego kodu, który w sumie już mam ale rozbudowuję aplikację i chcę dodać "fajerwerki" informujące w sposób wizualny, że ludzik zrobił coś źle i o tym dalej poniżej:
Problem 2 - który jeszcze nie powstał ale ukazał skalę problemu? Prawdopodobne drugie obejście hermetyzacji klas
postanowiłem dodać kolory dla pola QLineEdit aby informowało wizualnie użytkownika, że to co wpisał jest dobrze lub źle, więc dla testu ustawiłem kolory dla jednego pola, które przyjmuje adres IP - dla tego pola nie złamałem hermetyzacji ale przy większej ilości pól zaczyna się problem i zastanawiam się czy zrobię dobrze?
Bo nie chcę dla każdego pola pisać funkcji ustaw "odpowiedni kolor"
dla zobrazowania pokażę jak to wygląda dla jednego pola
przed wpisaniem lub po skasowaniu czegokolwiek - pole wygląda tak
podczas wprowadzania - nie znamy jeszcze wyniku validacji, pole wygląda tak
po wprowadzeniu poprawnego wpisu, który natychmiast zostaje zwavlidowany poprawnie, pole wprowadzania wygląda tak
no a skoro nie chcę powielać dużej ilości funkcji dla tego samego zadania, to wpadłem na pomysł, żeby zrobić jedną funkcję do tej pracy
czyli Mediator
ma funkcję void Mediator::errorValidate(Error::ValidationErrors errorCode, FieldType fieldType)
która sprawdza, jaki rodzaj błędu został wygenerowany i przez jakie pole
ale prawdziwa zabawa zaczyna się tutaj - bo mediator w końcu nie ma pojęcia, które konkretne pole poinformować o tym, że coś jest źle lub dobrze wpisane przez ludzika
i znowu wpadłem na pomysł aby do funkcji, które przesyłają wpisany tekst do mediatora, przesyłały również wskaźnik tego pola które ten tekst wysyła - kod niżej
void Page1::setIpAddress(const QString &address)
{
emit this->ipAddress(address); //tutaj jeszcze nie łamię hermetyzacji, bo jeszcze tego nie napisałem
}
ale czy przypadkiem nie złamię hermetyzacji, jeżeli zrobię coś takiego?
Page1::Page1(QWidget *parent): QWidget{parent}, mainVlayout(new QVBoxLayout(this))
{
this->setObjectName(QString("Page1"));
//dla uproszczenia usunąłem wszystko i zostawiłem, to na czym chcę się skupić
lineEditServerAddress = new QLineEdit(this); //pole, które pobiera adres IP od użytkownika
}
void Page1::setIpAddress(const QString &address)
{
emit this->ipAddress(address, lineEditServerAddress); //czy tutaj już łamię zasady hermetyzacji?
//bo w sumie wysyłam do mediatora adres prywatnej składowej klasy i potem robię sobie tam co chcę...
}
- screenshot-20241122121659.png (1 KB) - ściągnięć: 3
- screenshot-20241122121753.png (2 KB) - ściągnięć: 2
- screenshot-20241122121849.png (2 KB) - ściągnięć: 2