QT-wyśrodkowanie pozycji QLabel, błędny wskaźnik

0

witam, mam problem z tą funkcją:

void MainWindow::CreateChessBoard()
{
    ChessboardFrame = new QLabel(this);
    ChessboardFrame->resize(700,700);
    ChessboardFrame->move(0,0);
    ChessboardFrame->setAlignment(Qt::AlignVCenter);
    int x=75;
    int y=75;
    int c=75;
    Chessboard = new QLabel *[8];
    for(int i=0; i<8; ++i)
    {
        Chessboard[i] = new QLabel[8];
    }
    for(int i=0; i<8; ++i)
    {
        for(int j=0; j<8; ++j)
        {
            if(i%2==0)
            {
                if(j%2==0)
                {
                    Chessboard[i][j].setParent(ChessboardFrame);
                    Chessboard[i][j].setStyleSheet("QLabel { background-color : black; }");
                    Chessboard[i][j].resize(c,c);
                    Chessboard[i][j].move(x,y);
                    Chessboard[i][j].setText("Czarne");
                    //Chessboard[i][j].;
                }
                else
                {
                    Chessboard[i][j].setParent(ChessboardFrame);
                    Chessboard[i][j].setStyleSheet("QLabel { background-color : white; }");
                    Chessboard[i][j].resize(c,c);
                    Chessboard[i][j].move(x,y);
                    Chessboard[i][j].setText("Biale");
                    //Chessboard[i][j].;
                }
            }
            else
            {
                if(j%2==0)
                {
                    Chessboard[i][j].setParent(ChessboardFrame);
                    Chessboard[i][j].setStyleSheet("QLabel { background-color : white; }");
                    Chessboard[i][j].resize(c,c);
                    Chessboard[i][j].move(x,y);
                    Chessboard[i][j].setText("Biale");
                    //Chessboard[i][j].;
                }
                else
                {
                    Chessboard[i][j].setParent(ChessboardFrame);
                    Chessboard[i][j].setStyleSheet("QLabel { background-color : black; }");
                    Chessboard[i][j].resize(c,c);
                    Chessboard[i][j].move(x,y);
                    Chessboard[i][j].setText("Czarne");
                    //Chessboard[i][j].;
                }
            }
            x+=c;
        }
        x=c;
        y+=c;
    }
} 

1/chodzi o to, że program uruchamia się poprawnie (w trybie debug) ale wyrzuca info "invalid pointer".
2/Potrzebuję wyśrodkować QLabel w którego środku znajdują się czarno-białe prostokąciki :). Myślałem nad tym żeby pobrać rozmiar okna i przeliczyć sobie gdzie powinno znajdować się chessBoardFrame jednak nie umiem znaleźć klasy odpowiedzialnej za to działanie.
3/Jak sprawić aby okno dopasowywało się do wielkości szachownicy. W tej chwili zachowuje się tak jakby wielkość miało wpisaną na stałe. Może znów powinienem pobierać wielkość ChessBoardFrame i po odpowiedniej modyfikacji jakoś ustawiać wielkość tego okna(tylko jak?).

0

Nie lepiej użyć Buttonów? Mają przynajmniej sygnał kliknięcia.
Powinieneś użyć layouta, np. QGridLayout. Poczytaj też o tym, co zrobić żeby widget był kwadratowy (wystarczy że widget zawierający tą szachownicę będzie kwadratowy). QLabel nie jest dobrym "kontenerem" (jako kontener powinno się używać samego QWidgeta).

Swoją drogą można te generowanie uprościć: (i+j)%2==0 :p Wtedy true jest wtedy, gdy obie są parzyste lub nieparzyste, a false gdy jedna z nich nieparzysta. Tak więc dla jednego rządu true będą parzyste, a dla drugiego nieparzyste.

Jeszcze lepszym rozwiązaniem jest użycie QGraphicsView i sceny.

Co do invalid pointer, to chodzi o przetrzymywanie QLabeli. Problem jest taki, że widgety powinno się przetrzymywać jako wskaźniki, nawet jeśli są w tablicy. Inaczej mówiąc: nie **QLabel, tylko jak już to ***QLabel

//EDIT: Ucięło gwiazdki, poprawiłem

0

Dobra, zmieniłem nieco podejście i zgodnie z Waszymi wskazówkami staram się używać layoutów. Mam jednak problem bo z mojej szachownicy wyświetla się jedynie pierwszy wiersz i ostatnia kolumna. Zastanawiam się czy w ogóle można łączyć VBoxLayout z GridLayouti czy nie to stanowi problem.

 #include <mainwindow.h>
void ChessOperations::addChessBoard(QWidget *&Widget)
{
    HBoxLayout=new QHBoxLayout();
    ChessBoard=new QGridLayout();
    VBoxLayout=new QVBoxLayout(Widget);
    ChessFields=new QPushButton[64];
    PlayerMovement=new QPushButton("do Something");
    LineEdit=new QLineEdit();
    HBoxLayout->addWidget(PlayerMovement);
    HBoxLayout->addWidget(LineEdit);
    for(int i=0; i<8; ++i)
    {
        for(int j=0; j<8; ++j)
        {
            if(i%2==0)
            {
                if(j%2==0)
                {
                    (ChessFields+i+j)->setStyleSheet("background-color: white");
                }
                else
                {
                    (ChessFields+i+j)->setStyleSheet("background-color: black");
                }
            }
            else
            {
                if(j%2==0)
                {
                    (ChessFields+i+j)->setStyleSheet("background-color: black");
                }
                else
                {
                    (ChessFields+i+j)->setStyleSheet("background-color: white");
                }
            }
            ChessBoard->addWidget(ChessFields+i+j, i, j);
            ChessBoard->setSpacing(0);
        }
    }
    VBoxLayout->addLayout(HBoxLayout);
    VBoxLayout->addLayout(ChessBoard);
    Widget->setLayout(VBoxLayout);
}
0

Po co podajesz Widgeta zarówno w konstruktorze layoutu jak i potem znów przypisujesz layout do tego widgetu?

Dalej robisz ten sam błąd: new QPushButton[64];. powinno być new QPushButton*[64]; i każdy button tworzony osobno, inaczej jest problem z czyszczeniem.

No i źle się też poruszasz po tablicy. przemieszczasz o +i+j, powinno być raczej +i+8*j.

Co do stylu: przypisujesz je globalnie, tzn. na cały obszar, a nie sam przycisk, dlatego jest na cały obszar widgetu. "QPushButton{background-color: white:} jest lepszym wyjściem, jeśli buttony mają być rysowane.

Trochę mi się nudziło, w C++ i Qt dawno nie pisałem, więc tak dla przypomnienia napisałem generowanie szachownicy i gotowy mechanizm eventów. Klasa Field rozszerza QPushButton, może przechowywać info o swoich współrzędnych, typie figury jaka się na nim znajduje i właścicielu. Dzięki temu może wyemitować przy kliknięciu sygnał mouseClicked zawierający w argumentach swoje współrzędne (nie trzeba potem wg. źródła szukać).
Poza tym jest nadpisana metoda rysująca dzięki czemu można narysować sobie na tym buttonie co się chce, polecam zapoznać się z QPainter i rysowaniem plików SVG, grafiki znajdziesz na np. http://www.openclipart.org/ .

Poza tym jest tam też przykład widgetu który zawsze jest kwadratowy (tak, wiem, użyłem prymitywnego boolowego locka, ale działa)

Projekt w załączniku.

0

Nie mogę tego ogarnąć. Jak dam QPushButton *** cos; i stworze sobie powiedzmy te 64 buttony to jak się do nich odwołać?

cos[i][j]->zrob_cos(); ?

0

Zamotałeś za bardzo
Primo,jeśli ja chciałbym mieć szachownicę,to zrobiłbym ją jako 1 QWidget z własnym paint eventem malującym pola.
Secundo,jeśli już koniecznie chciałbym,aby każde pole szachownicy było osobnym widgetem oparłbym je na podstawowym QWidgecie.Tworzylyby układ 8x8 i wsadzone byłyby w grid layout,który siedziałby w jakimś zbiorczym QWidgecie.Podejście to ma pewną wadę polegającą na tym,że w przypadku szachownicy mogącej zmieniać rozmiar będzie trochę zabawy z ograniczeniem kształtu widgetów do kwadratu.Dlatego lepiej mieć 1 nadrzędnego widgeta na to

0

problem w tym, że taki sposób jak opisałem wyżej nie działa. Zwraca, że program nieoczekiwanie zakończył działanie. A z QT dopiero zaczynam w związku z czym uczę się robiąc projekt gry w szachy.

0
Puchaczov napisał(a)

A z QT dopiero zaczynam w związku z czym uczę się robiąc projekt gry w szachy.

tylko że twój problem nie wynika bezpośrednio z nieznajomości Qt, a podstaw samego języka, w którym wykorzystujesz ten framework. Tworzysz takie konstrukcje, a nie potrafisz ich wykorzystać. Qt za ciebie nic nie wymyśli, jedynie pomoże zrealizować i ułatwić dążenie do rozwiązania problemu, który sobie wyznaczysz.

0

Tak, to prawda. Jednak nie wiem jak się odnieść do takiego wskaźnika i proszę o pokazanie mi tego :)

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