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

Odpowiedz Nowy wątek
2011-08-28 01:13
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?).

edytowany 1x, ostatnio: Puchaczov, 2011-08-28 01:20

Pozostało 580 znaków

2011-08-28 02:02
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

edytowany 1x, ostatnio: Razi91, 2011-08-28 02:46
A nawet QLabel* ;) - MasterBLB 2011-08-28 02:43

Pozostało 580 znaków

2011-08-28 22:16
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);
}

Pozostało 580 znaków

2011-08-28 22:54
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.

Pozostało 580 znaków

2011-08-30 22:58
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(); ?

Pozostało 580 znaków

2011-08-30 23:03
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


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
edytowany 1x, ostatnio: MasterBLB, 2011-08-30 23:11

Pozostało 580 znaków

2011-08-30 23:10
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.

Naucz się używać Designera do tworzenia form.Moocno ułatwia zabawy z layoutem,ponadto od razu masz podgląd,jak będzie wyglądało po uruchomieniu to co piszesz - MasterBLB 2011-08-30 23:14
próbowałem tylko, że miałem spory problem z podłączeniem slotów do tego co zrobiłem. Zdecydowanie lepiej mi wychodzi napisanie samemu tego xD - Puchaczov 2011-08-30 23:18
Gdzie tu jest problem??Dostajesz klasę Ui::nazwaFormy,w której wszystko co do niej wsadziłeś siedzi.Tworzysz zatem jej instancję,wywołujesz uiInstanceName.setupUI(this) a potem masz np connect(uiInstanceName.someButtonOnForm,SIGNAL(clicked()),this,SLOT(whatever())); - MasterBLB 2011-08-30 23:43

Pozostało 580 znaków

2011-08-30 23:51
hmmm
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.

Pozostało 580 znaków

2011-08-30 23:57
0

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

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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