19. Qt

19. Qt

19. Qt

18 май 2016

Milestone

25 май 2015

Какво очакваме?

Публично достъпно хранилище - github, bitbucket, self-hosted

LICENSE, README

Подкарани библиотеки/frameworks, които смятате да използвате

Малко код, показващ идея как смятате да напишете проекта си

Ще пуснем новина с по - подробно обяснение

Meta

Платформа за cross-platform разработване на приложения

Поддържани платформи

Неофициални

Deprecated

В началото бе QApplication

#include <QApplication>
#include <QLabel>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QLabel *label = new QLabel("Hello Qt!");
    label->show();
    return app.exec();
}

Същото ама на Python (PyQt)

import sys
from PyQt5 import Qt

app = Qt.QApplication(sys.argv)
label = Qt.QLabel("Hello Qt!")
label.show()
app.exec_()

Първоначален план

Прозорец

Имаме опцията да използваме `QMainWindow`. Това ни дава:

В нашия случай това ще е overkill. Прозорецът ни може да е един обикновен `QWidget`.

Layouts

Тъй като ще има повече от един widget, ще трябва да ги разположим по някакъв начин

Qt ни дава няколко такива:

  • QHBoxLayout
  • QVBoxLayout
  • QFormLayout
  • QGridLayout

Layouts

nextPieceLabel = QLabel()
nextPieceLabel.setFrameStyle(QFrame.Box | QFrame.Raised)
nextPieceLabel.setAlignment(Qt.AlignCenter)
self.board.setNextPieceLabel(nextPieceLabel)

scoreLcd = QLCDNumber(5)
scoreLcd.setSegmentStyle(QLCDNumber.Filled)
levelLcd = QLCDNumber(2)
levelLcd.setSegmentStyle(QLCDNumber.Filled)
linesLcd = QLCDNumber(5)
linesLcd.setSegmentStyle(QLCDNumber.Filled)

startButton = QPushButton("&Start")
startButton.setFocusPolicy(Qt.NoFocus)
quitButton = QPushButton("&Quit")
quitButton.setFocusPolicy(Qt.NoFocus)
pauseButton = QPushButton("&Pause")
pauseButton.setFocusPolicy(Qt.NoFocus)

Layouts

За нашите цели изглежда най-удачно да ползваме QGridLayout

Можем просто да извикваме addWidget метода му, за да добавяме на определена позиция

layout = QGridLayout()
layout.addWidget(self.createLabel("NEXT"), 0, 0)
layout.addWidget(nextPieceLabel, 1, 0)
layout.addWidget(self.createLabel("LEVEL"), 2, 0)
layout.addWidget(levelLcd, 3, 0)
layout.addWidget(startButton, 4, 0)
layout.addWidget(self.board, 0, 1, 6, 1)
layout.addWidget(self.createLabel("SCORE"), 0, 2)
layout.addWidget(scoreLcd, 1, 2)
layout.addWidget(self.createLabel("LINES REMOVED"), 2, 2)
layout.addWidget(linesLcd, 3, 2)
layout.addWidget(quitButton, 4, 2)
layout.addWidget(pauseButton, 5, 2)
self.setLayout(layout)

self.setWindowTitle("Tetrix")
self.resize(550, 370)

Елементите

Ние ще използваме:

Сигнали и слотове

Сигнали и слотове

Вместо events или callbacks, Qt изпраща сигнал от потребителско действие в слот (функция)

startButton.clicked.connect(self.board.start)
pauseButton.clicked.connect(self.board.pause)
quitButton.clicked.connect(QApplication.instance().quit)
self.board.scoreChanged.connect(scoreLcd.display)
self.board.levelChanged.connect(levelLcd.display)
self.board.linesRemovedChanged.connect(linesLcd.display)

Сигнали и слотове

Можем да създаваме наши сигнали и да ги "излъчваме"

scoreChanged = pyqtSignal(int)
levelChanged = pyqtSignal(int)
linesRemovedChanged = pyqtSignal(int)

self.linesRemovedChanged.emit(self.numLinesRemoved)
self.scoreChanged.emit(self.score)
self.levelChanged.emit(self.level)

По-интересни проблеми

Добра отправна точка

Qt е необятен. Нека разгледаме една имплементация на тетрис.

тук

Кадри

Ако правим игра, а не просто приложение с графичен интерфейс,опираме до това, че трябва да имаме фреймове. N пъти в секундаще трябва да преначертаваме дадена област, лъжейки човешкотооко, че разни неща се движат. В нашия случай, това е борда.

class TetrixBoard(QFrame):
    BoardWidth = 10
    BoardHeight = 22
    scoreChanged = pyqtSignal(int)
    levelChanged = pyqtSignal(int)
    linesRemovedChanged = pyqtSignal(int)

    def start(self):...
    def pause(self):...
    def paintEvent(self):...
    def keyPressEvent(self):...
    def keyPressEvent(self):...
    def timerEvent(self, event):...
    def oneLineDown(self):...
    def dropDown(self):...
    ...

Collision detection

4 основни подхода:

But wait…

We kid you not, Qt е НЕОБЯТЕН

Въпроси?