用qt写一个GUI的棋盘覆盖,要能实现动态呈现,可以前进或者退出骨牌的代码
时间: 2023-12-06 22:42:58 浏览: 88
suanfa.rar_A算法 报告_棋盘覆盖_棋盘覆盖问题_算法 实验报告_算法 报告
以下是一个基于Qt的棋盘覆盖GUI的示例代码,可以实现前进或退出骨牌的功能:
```cpp
#include <QtWidgets>
class DominoWidget : public QWidget
{
public:
explicit DominoWidget(QWidget *parent = nullptr);
private:
void paintEvent(QPaintEvent *) override;
void mousePressEvent(QMouseEvent *) override;
QVector<QPair<int, int>> m_dominoes; // 存储每个骨牌的位置
int m_currIndex; // 当前选中的骨牌在m_dominoes中的索引
QPoint m_dragStartPos; // 鼠标拖动起始点的位置
const int m_boardSize = 500; // 棋盘大小
const int m_dominoSize = 50; // 骨牌大小
const int m_dominoSpacing = 10; // 骨牌间距
};
DominoWidget::DominoWidget(QWidget *parent)
: QWidget(parent), m_currIndex(-1)
{
// 初始化骨牌位置
for (int i = 0; i < 10; ++i) {
m_dominoes.append(qMakePair(i * (m_dominoSize + m_dominoSpacing), m_boardSize - m_dominoSize));
}
}
void DominoWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
// 绘制棋盘
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::white);
painter.drawRect(0, 0, m_boardSize, m_boardSize);
// 绘制骨牌
painter.setBrush(Qt::black);
for (const auto &pos : m_dominoes) {
painter.drawRect(pos.first, pos.second, m_dominoSize, m_dominoSize);
}
}
void DominoWidget::mousePressEvent(QMouseEvent *event)
{
// 找到当前点击的骨牌
for (int i = 0; i < m_dominoes.size(); ++i) {
const auto &pos = m_dominoes.at(i);
if (QRect(pos.first, pos.second, m_dominoSize, m_dominoSize).contains(event->pos())) {
m_currIndex = i;
m_dragStartPos = event->pos();
break;
}
}
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
DominoWidget dominoWidget;
dominoWidget.setFixedSize(520, 520);
dominoWidget.show();
return app.exec();
}
```
这个示例代码中,我们使用了QVector存储每个骨牌的位置信息。在paintEvent中,我们遍历m_dominoes并绘制每个骨牌。在mousePressEvent中,我们通过遍历m_dominoes找到当前点击的骨牌,并记录下当前选中的骨牌的索引和鼠标拖动起始点的位置。现在我们需要实现鼠标拖动功能:
```cpp
void DominoWidget::mouseMoveEvent(QMouseEvent *event)
{
if (m_currIndex != -1) {
// 计算骨牌的新位置
const auto &pos = m_dominoes.at(m_currIndex);
int newX = pos.first + event->x() - m_dragStartPos.x();
int newY = pos.second + event->y() - m_dragStartPos.y();
// 边界检查
if (newX < 0) {
newX = 0;
} else if (newX > m_boardSize - m_dominoSize) {
newX = m_boardSize - m_dominoSize;
}
if (newY < 0) {
newY = 0;
} else if (newY > m_boardSize - m_dominoSize) {
newY = m_boardSize - m_dominoSize;
}
// 更新骨牌位置
m_dominoes[m_currIndex] = qMakePair(newX, newY);
m_dragStartPos = event->pos();
update(); // 重绘窗口
}
}
void DominoWidget::mouseReleaseEvent(QMouseEvent *)
{
m_currIndex = -1; // 取消选中状态
}
void DominoWidget::keyPressEvent(QKeyEvent *event)
{
if (m_currIndex != -1) {
if (event->key() == Qt::Key_Left) { // 向左移动
m_dominoes[m_currIndex].first -= m_dominoSize + m_dominoSpacing;
if (m_dominoes[m_currIndex].first < 0) {
m_dominoes[m_currIndex].first = m_boardSize - m_dominoSize;
}
update();
} else if (event->key() == Qt::Key_Right) { // 向右移动
m_dominoes[m_currIndex].first += m_dominoSize + m_dominoSpacing;
if (m_dominoes[m_currIndex].first > m_boardSize - m_dominoSize) {
m_dominoes[m_currIndex].first = 0;
}
update();
} else if (event->key() == Qt::Key_Up) { // 向上移动
m_dominoes[m_currIndex].second -= m_dominoSize + m_dominoSpacing;
if (m_dominoes[m_currIndex].second < 0) {
m_dominoes[m_currIndex].second = m_boardSize - m_dominoSize;
}
update();
} else if (event->key() == Qt::Key_Down) { // 向下移动
m_dominoes[m_currIndex].second += m_dominoSize + m_dominoSpacing;
if (m_dominoes[m_currIndex].second > m_boardSize - m_dominoSize) {
m_dominoes[m_currIndex].second = 0;
}
update();
}
}
}
```
在mouseMoveEvent中,我们计算出骨牌的新位置,并更新m_dominoes中对应的元素,然后调用update()重新绘制窗口。在mouseReleaseEvent中,我们取消当前选中的骨牌状态。在keyPressEvent中,我们监听方向键事件,实现骨牌的前进和退出功能。
阅读全文