#StackBounty: #macos #environment-variables #gui How to set environment variables on MacOS using a GUI?

Bounty: 250

I’m trying to provide instructions to several people on how to set an environment variable in MacOS.

I want the variable to be permanent, not require reboot, and it must work for all gui applications.

Unfortunately, any solution that requires vim or even nano isn’t going to fly.

How exactly can this be done only using a gui application? (And the simpler the better)


Get this bounty!!!

#StackBounty: #graphics #gui WxWidget based programs fail to refresh drawings

Bounty: 50

I am trying to pinpoint a problem where WxWidget based programs (so far Audacity and the Gnuplot wxt terminal) fail to show and refresh content in their "plotting" part of the window. Main UX seems to work fine.

Here’s an example:

Audacity and GnuPlot not refreshing

You can see that the part of the Audacity window where the recordings are does not refresh (this happens also during recording, making Audacity pretty much unusable). The same happens in the right side window marked by "Figure 1", which is spawned by running gnuplot -p with a wxt terminal.

As the only link between the two applications is WxWidgets, I think that it’s where the trouble is; however I’m not sure what I can do about it.

SYSTEM INFO:

LSB Version:    core-11.1.0ubuntu2-noarch:security-11.1.0ubuntu2-noarch
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.1 LTS
Release:    20.04
Codename:   focal
--------------------------------------------------
LXQt Desktop Toolbox - Technical Info
  LXQt About Version:     0.14.1
  LXQt Version:           0.14.1
  Qt:                     5.12.8
  Build type:             Release
--------------------------------------------------
Openbox 3.6.1
--------------------------------------------------
08:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] (rev e7)
       configuration: driver=amdgpu latency=0
server glx vendor string: SGI
client glx vendor string: Mesa Project and SGI
    Vendor: X.Org (0x1002)
OpenGL vendor string: X.Org


Get this bounty!!!

#StackBounty: #gui #gtk #gtk3 #gtk2 Traditional scrollbars in GTK2 applications

Bounty: 100

To enable traditional scrollbars with scroll buttons in GTK3 applications I have added the file ~/.config/gtk-3.0/gtk.css with the content

scrollbar {
        -GtkScrollbar-has-backward-stepper: true;
        -GtkScrollbar-has-forward-stepper: true;
}

scrollbar slider {
        border: 0;
        border-radius: 0;
        min-width: 15px;
        min-height: 15px;
}

The first screenshot below shows the result in the GTK3 application Pluma. How do I get the same kind of scrollbars in GTK2 applications like PCManFM in the second screenshot below?

Text editor with traditional scrollbar

enter image description here


Get this bounty!!!

#StackBounty: #server #backup #gui Backups initiated to pull from remote Ubuntu hosts

Bounty: 50

I am looking for a user-friendly solution to back-up a small cluster of Ubuntu servers. Ideally, I’d like to take a minimal representation of the standard configuration (i.e. a list of installed Ubuntu packages) then a copy of all edited configuration and user files. While ‘unusual’ (I suspect) I’d like to do this by running the backup software on a host (Windows or Ubuntu) with a lot of local disk available – and use it to back-up remote servers – ideally without requiring any special services to be installed on the systems that require backups.

I’m struggling to find a backup tool that works this way (i.e. with a UI on the host with the backup drives locally attached – looking to back-up data from remote servers over SSH/rsync.

I realise that I could write some scripts to do this – but I’m really looking for a GUI that will make it easy for me to manage ongoing incremental backups and to restore anything from an entire system to an individual file in the case of a failure.

Are there any Ubuntu-supported backup tools that work this way (i.e pulling data from a remote live system to the system storing the backups – versus pushing data from an operational system to remote storage)?


Get this bounty!!!

#StackBounty: #debian #wifi #networkmanager #cinnamon #gui WiFi Settings Missing in Network Manager after boot/resume

Bounty: 100

I’m running Debian 10 Cinnamon, and recently I’ve noticed that the WiFi settings within Network Manager(nm-applet) are completely missing on every boot/resume from suspend unless you manually restart NetworkManager. Previously, I could click the network icon in the bottom right of the page, click Network Settings, and I would be brought to a menu which listed the different interfaces, in this case wired and wireless. Now, there is only “Wired” and “Network Proxy” shown. All previously saved WiFi settings are still working, but I cannot modify settings as I was previously able to. The nm-connection-editor works fine. The saved Wireless connection can auto connect and works fine in the background, but I have no way to add a new network or easily control the wireless settings for a network via nm-applet anymore.

Why is this menu vanishing on boots/resumes? What can I do to fix it? Heres an image of the missing menu. enter image description here
Note, where it says “Wired” on the left side column, there should be another option for “WiFi”, as was there when Debian was initially installed.

I have found that running sudo pgrep NetworkManager | xargs sudo kill -9; fixes the issue, but what could be the root cause? This was not happening on a fresh install. I have also found that it happens on every boot, or resuming from suspend, but if NetworkManager is restarted after boot/resume from suspend manually, the issue is fixed.

In addition, I have found that if I cat ~/.xsession-errors, there are many errors relating to wireless and NetworkManager, such as:

Cjs-Message: 11:08:41.602: JS LOG: An active wireless connection, in infrastructure mode, involves no access point?

nm-tray: void NmModelPrivate::onConnectionAdded(const QString&) /org/freedesktop/NetworkManager/Settings/6  is currently invalid...

Cjs-Message: 11:09:21.384: JS LOG: [LookingGlass/error] a.connection is null

(cinnamon:1364): Cjs-WARNING **: 11:08:45.677: JS ERROR: TypeError: apObj.item.updateAccessPoints is not a function
anonymous/NMDeviceWireless.prototype._accessPointRemoved@/usr/share/cinnamon/applets/network@cinnamon.org/applet.js:1387:13

(cinnamon:1364): Cjs-WARNING **: 11:08:46.750: JS ERROR: TypeError: ssid is null
ssidToLabel@/usr/share/cinnamon/applets/network@cinnamon.org/applet.js:66:9

I am using a Wifi AP with a hidden ssid, which seems to cause some of these errors. Using a non-hidden ssid and deleting all profiles relating to the hidden one does not solve the issue.


Get this bounty!!!

#StackBounty: #debian #wifi #networkmanager #cinnamon #gui WiFi Settings Missing in Network Manager

Bounty: 50

I’m running Debian 10 Cinnamon, and recently I’ve noticed that the WiFi settings within Network Manager(nm-applet) are completely missing. Previously, I could click the network icon in the bottom right of the page, click Network Settings, and I would be brought to a menu which listed the different interfaces, in this case wired and wireless. Now, there is only “Wired” and “Network Proxy” shown. All previously saved WiFi settings are still working, but I cannot modify settings as I was previously able to. The nm-connection-editor works fine. The saved Wireless connection can auto connect and works fine in the background, but I have no way to add a new network or easily control the wireless settings for a network via nm-applet anymore.

Why is this menu vanishing? What can I do to fix it? Heres an image of the missing menu. enter image description here
Note, where it says “Wired” on the left side column, there should be another option for “WiFi”, as was there when Debian was initially installed.

I have found that running sudo rfkill unblock all; sudo pgrep NetworkManager | xargs sudo kill -9; fixes the issue, but what could be the root cause? This was not happening on a fresh install.


Get this bounty!!!

#StackBounty: #18.04 #gui #gnome-shell #tty How to enable: Switch back to running GUI from TTY in 18.04

Bounty: 50

I recently installed Ubuntu 18.04 (previously 16.04) and an important feature is missing: the option to switch between GUI and TTY.

From the GUI I can switch to one of 5 TTY, by CtrlAltF2 to CtrlAltF6. I can login in the tty, do whatever I wish. When I Press AltF1, I get to the login-screen, not back to running GUI session. AltF7 leads to a black screen.

When I switch to the login screen, and login, I get a fresh GUI-Login. The programs have been terminated, the unsaved data and status is lost. This is annoying.

In previous versions, AltF7 brought me to the original, running GUI. AltF1 brought me to the console of the GUI. This is how I want it to be. The particular order of screens does not matter – the crucial item is to get back.

How can I customize 18.04 in this way?

PS: I basically have the default 18.04.4 desktop install using GNOME-shell (not unity). The only thing remotely non-standard is that it is MBR/Legacy, not GPT/UEFI install.


Get this bounty!!!

#StackBounty: #c++ #gui #c++17 #snake-game #qt C++ Snake game using Qt-framework

Bounty: 50

I made a QT version of “Snake console game in C++” using Qt Creator 4.9.0 on Windows 7:

Picture of the running game

I would like to know what can be improved, focused on the QT stuff since im new to it.
I seperated the program as followed:

QT-Classes

  • SnakeWindow: Contains the GUI Elements like the Buttons, LCD Displays and The SnakeBoard to display the game. It also sends the button signals to the SnakeBoard and receives the score and delay to be displayed in the LCD Displays.
  • SnakeBoard: This is basically an extended QFrame which runs all the events like moving the snake and reacting to button events. It uses the non QT class Board which was already used in the console snakeGame

Non-QT-Classes

  • Board: Describes the field were the snake is moved arround. Also generates food at a random position, let the snake grow and check for
    the game over conditions wall or snake hit. It contains a Snake to
    handle snake related stuff.
  • Snake: Represents the Snake. Places the snake in the middle of the board. Enables to move the snake in all directions. Also the
    snake can be grown.

main.cpp

#include "SnakeWindow.h"

#include <QApplication>
#include <QDebug>

int main(int argc, char *argv[])
    try{
    QApplication app(argc, argv);
    SnakeWindow window;
    //window.show();
    window.showFullScreen();
    return app.exec();
}
catch(...) {
    qDebug() << "Unknown Errorn";
}

SnakeWindow.h

#ifndef SNAKEWINDOW_H
#define SNAKEWINDOW_H

#include <QWidget>

namespace Ui {
class SnakeWindow;
}

class SnakeWindow : public QWidget
{
    Q_OBJECT

public:
    explicit SnakeWindow(QWidget *parent = nullptr);
    ~SnakeWindow();

private:
    Ui::SnakeWindow *ui;
};



#endif // SNAKEWINDOW_H

SnakeWindow.cpp

#include "SnakeWindow.h"
#include "ui_SnakeWindow.h"

SnakeWindow::SnakeWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SnakeWindow)
{
    ui->setupUi(this);

    connect(ui->startButton, &QPushButton::clicked,
            ui->snakeBoard, &SnakeBoard::start);
    connect(ui->quitButton, &QPushButton::clicked,
            qApp, &QApplication::quit);
    connect(ui->pauseButton, &QPushButton::clicked,
            ui->snakeBoard, &SnakeBoard::pause);
    connect(ui->snakeBoard, &SnakeBoard::scoreChanged,
            [=](int score) {ui->scoreLcd->display(score);});
    connect(ui->snakeBoard, &SnakeBoard::delayChanged,
            [=](int level) {ui->delayLcd->display(level);});
}

SnakeWindow::~SnakeWindow()
{
    delete ui;
}

SnakeBoard.h

#ifndef SNAKEBOARD_H
#define SNAKEBOARD_H

#include <QFrame>
#include <QBasicTimer>

#include "Board.h"

class SnakeBoard : public QFrame {
    Q_OBJECT
public:
    SnakeBoard(QWidget* parent = nullptr);

    QSize sizeHint() const override;
    QSize minimumSizeHint() const override;

public slots:
    void start();
    void pause();
    void gameOver();

signals:
    void scoreChanged(int score);
    void delayChanged(int delay);

protected:
    void paintEvent(QPaintEvent *event) override;
    void keyPressEvent(QKeyEvent *event) override;
    void timerEvent(QTimerEvent *event) override;

private:
    int squareWidth();
    int squareHeight();

    void drawField(
        QPainter& painter, int x, int y, snakeGame::FieldType fieldType);

    void drawWall(QPainter& painter, int x, int y);
    void drawFood(QPainter& painter, int x, int y);

    void drawSnakeHead(QPainter& painter, int x, int y);
    void drawSnakeSegment(QPainter& painter, int x, int y);

    static constexpr auto boardWidth{40};
    static constexpr auto boardHeight{20};

    static constexpr auto initDelay{300};
    static constexpr auto initPoints{100};

    QBasicTimer timer;

    snakeGame::Board board{boardWidth, boardHeight};
    snakeGame::SnakeDirection snakeDirection{snakeGame::SnakeDirection::right};

    bool isStarted{false};
    bool isPaused{false};
    bool isGameOver{false};
    bool snakeWasMoved{true};
    int score{0};
    int delay{initDelay};
    int points{initPoints};
};

#endif // SNAKEBOARD_H

SnakeBoard.cpp

#include "SnakeBoard.h"

#include <QKeyEvent>
#include <QColor>
#include <QPainter>
#include <QRgb>
#include <QTimerEvent>

#include <QDebug>

using namespace snakeGame;

SnakeBoard::SnakeBoard(QWidget* parent)
    : QFrame{parent},
    board{boardWidth, boardHeight},
    snakeDirection{SnakeDirection::right}
{
    setFrameStyle(QFrame::Panel | QFrame::Sunken);
    setFocusPolicy(Qt::StrongFocus);

    board.updateSnakePosition();
    board.placeFood();
}

QSize SnakeBoard::sizeHint() const
{
    return QSize(boardWidth * 15 + frameWidth() * 2,
                 boardHeight * 15 + frameWidth() * 2);
}

QSize SnakeBoard::minimumSizeHint() const
{
    return QSize(boardWidth * 5 + frameWidth() * 2,
                 boardHeight * 5 + frameWidth() * 2);
}

void SnakeBoard::start()
{
    if (isGameOver) {
        isGameOver = false;
        board.reset();
        board.updateSnakePosition();
        board.placeFood();

        score = 0;
        points = initPoints;
        delay = initDelay;
    }

    if (isPaused)
        return;

    isStarted = true;

    emit scoreChanged(score);
    emit delayChanged(delay);

    timer.start(delay, this);
}

void SnakeBoard::pause()
{
    if (!isStarted)
        return;

    isPaused = !isPaused;
    if (isPaused) {
        timer.stop();
    }
    else {
        timer.start(delay, this);
    }
    update();
}

void SnakeBoard::gameOver()
{
    timer.stop();
    isGameOver = true;
    isStarted = false;
}

void SnakeBoard::paintEvent(QPaintEvent *event)
{
    QFrame::paintEvent(event);

    QPainter painter(this);
    QRect rect = contentsRect();


    if(isGameOver) {
        QFont font;
        font.setPixelSize(20);
        painter.setFont(font);
        painter.drawText(rect, Qt::AlignCenter, tr("Game Over"));
        return;
    }

    if(!isStarted) {
        QFont font;
        font.setPixelSize(20);
        painter.setFont(font);
        painter.drawText(rect, Qt::AlignCenter, tr(
            "Press startn Use arrow keys to control the Snake"));
        return;
    }

    if (isPaused) {
        QFont font;
        font.setPixelSize(20);
        painter.setFont(font);
        painter.drawText(rect, Qt::AlignCenter, tr("Pause"));
        return;
    }

    auto boardTop = rect.bottom() - boardHeight * squareHeight();

    for (int i = 0; i < boardHeight; ++i) {
        for (int j = 0; j < boardWidth; ++j) {
            auto fieldType =
                board.fieldTypeAt(
                    static_cast<std::size_t>(j),
                    static_cast<std::size_t>(i));
            drawField(painter, rect.left() + j * squareWidth(),
                      boardTop + i * squareHeight(), fieldType);
        }
    }
}


void SnakeBoard::keyPressEvent(QKeyEvent *event)
{
    auto key = event->key();

    if (key == Qt::Key_P) {
        emit pause();
    }
    if (key == Qt::Key_Space) {
        emit start();
    }
    else if (!isStarted || isGameOver || !snakeWasMoved) {
        QFrame::keyPressEvent(event);
        return;
    }

    switch (key) {
    case Qt::Key_Left:       
        if (snakeDirection != SnakeDirection::right) {
            snakeDirection = SnakeDirection::left;
            snakeWasMoved = false;
        }
        break;
    case Qt::Key_Right:
        if (snakeDirection != SnakeDirection::left) {
            snakeDirection = SnakeDirection::right;
            snakeWasMoved = false;
        }
        break;
    case Qt::Key_Down:
        if (snakeDirection != SnakeDirection::up) {
            snakeDirection = SnakeDirection::down;
            snakeWasMoved = false;
        }
        break;
    case Qt::Key_Up:
        if (snakeDirection != SnakeDirection::down) {
            snakeDirection = SnakeDirection::up;
            snakeWasMoved = false;
        }
        break;
    default:
        QFrame::keyPressEvent(event);
    }
}

void SnakeBoard::timerEvent(QTimerEvent *event)
{
    if (isGameOver){
        QFrame::timerEvent(event);
        return;
    }

    if (event->timerId() == timer.timerId()) {

        board.moveSnake(snakeDirection);
        snakeWasMoved = true;

        if (board.snakeHitFood()) {
            board.eatFood();
            board.growSnake();
            board.updateSnakePosition();
            board.placeFood();
            score += points;
            points += static_cast<double>(initDelay / delay) * initPoints;
            delay -= 4;

            emit scoreChanged(score);
            emit delayChanged(delay);
        }
        else if (board.snakeHitWall() || board.snakeHitSnake()) {
            emit gameOver();
        }
        else {
            board.updateSnakePosition();
        }

        update();

        timer.start(delay, this);
    }
    else {
        QFrame::timerEvent(event);
    }
}

int SnakeBoard::squareWidth()
{
    return contentsRect().width() / boardWidth;
}

int SnakeBoard::squareHeight()
{
    return contentsRect().height() / boardHeight;
}

void SnakeBoard::drawField(
    QPainter& painter, int x, int y, snakeGame::FieldType fieldType)
{
    switch(fieldType){
    case FieldType::empty:
        break;
    case FieldType::wall:
        drawWall(painter, x, y);
        break;
    case FieldType::food:
        drawFood(painter, x, y);
        break;
    case FieldType::snakeHead:
        drawSnakeHead(painter, x, y);
        break;
    case FieldType::snakeSegment:
        drawSnakeSegment(painter, x, y);
        break;
    }
}

void SnakeBoard::drawWall(QPainter& painter, int x, int y)
{
    constexpr auto colorBrown = 0xbf8040;

    QColor color = QRgb{colorBrown};
    painter.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2,
                     color);

    painter.setPen(color.light());
    painter.drawLine(x, y + squareHeight() - 1, x, y);
    painter.drawLine(x, y, x + squareWidth() - 1, y);

    painter.setPen(color.dark());
    painter.drawLine(x + 1, y + squareHeight() - 1,
                     x + squareWidth() - 1, y + squareHeight() - 1);
    painter.drawLine(x + squareWidth() - 1, y + squareHeight() - 1,
                     x + squareWidth() - 1, y + 1);
}

void SnakeBoard::drawFood(QPainter& painter, int x, int y)
{
    constexpr auto colorRed = 0xff0000;
    QColor color = QRgb{colorRed};
    painter.setPen(color.light());
    painter.setBrush(QBrush{color});
    painter.drawEllipse(x +1,y +1,squareWidth() -3, squareHeight() -3);
}

void SnakeBoard::drawSnakeHead(QPainter& painter, int x, int y)
{
    constexpr auto colorDarkerLimeGreen = 0x00b300;

    QColor color = QRgb{colorDarkerLimeGreen};
    painter.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2,
                     color);

    painter.setPen(color.light());
    painter.drawLine(x, y + squareHeight() - 1, x, y);
    painter.drawLine(x, y, x + squareWidth() - 1, y);

    painter.setPen(color.dark());
    painter.drawLine(x + 1, y + squareHeight() - 1,
                     x + squareWidth() - 1, y + squareHeight() - 1);
    painter.drawLine(x + squareWidth() - 1, y + squareHeight() - 1,
                     x + squareWidth() - 1, y + 1);
}

void SnakeBoard::drawSnakeSegment(QPainter& painter, int x, int y)
{
    constexpr auto colorLimeGreen = 0x00e600;

    QColor color = QRgb{colorLimeGreen};
    painter.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2,
                     color);

    painter.setPen(color.light());
    painter.drawLine(x, y + squareHeight() - 1, x, y);
    painter.drawLine(x, y, x + squareWidth() - 1, y);

    painter.setPen(color.dark());
    painter.drawLine(x + 1, y + squareHeight() - 1,
                     x + squareWidth() - 1, y + squareHeight() - 1);
    painter.drawLine(x + squareWidth() - 1, y + squareHeight() - 1,
                     x + squareWidth() - 1, y + 1);
}

Board.h

#ifndef BOARD_H
#define BOARD_H

#include "Snake.h"

#include <vector>
#include <random>
#include <iosfwd>

namespace snakeGame {

    enum class SnakeDirection;

    enum class FieldType {
        empty,
        snakeSegment,
        snakeHead,
        wall,
        food
    };

    enum class SnakeDirection {
        up, right, down, left
    };

    class Board
    {
    public:
        Board(std::size_t width, std::size_t height);

        void reset();

        void placeFood();
        void updateSnakePosition();
        bool snakeHitFood() const;
        void eatFood();
        void growSnake();
        bool snakeHitWall() const;
        bool snakeHitSnake() const;
        void moveSnake(SnakeDirection snakeDirection);

        void debugPrintSnakeCoordinates();

        FieldType fieldTypeAt(std::size_t x, std::size_t y);
    private:
        std::vector<std::vector<FieldType>> initFieldWithWalls(
            std::size_t width, std::size_t height);
        void removeOldSnakePosition(const std::vector<SnakeSegment>& body);
        void addNewSnakePosition(const std::vector<SnakeSegment>& body);

        const std::size_t mWidth;
        const std::size_t mHeight;

        Snake mSnake;
        std::vector<std::vector<FieldType>> mFields;

        std::random_device mRandomDevice;
        std::default_random_engine mGenerator;
        std::uniform_int_distribution<std::size_t> mWidthDistribution;
        std::uniform_int_distribution<std::size_t> mHeightDistribution;

        friend std::wostream& operator<<(std::wostream& os, const Board& obj);
    };

    std::wostream& operator<<(std::wostream& os, const Board& obj);

}
#endif

Board.cpp

#include "Board.h"

#include <algorithm>
#include <iostream>

namespace snakeGame {

    Board::Board(std::size_t width, std::size_t height)
        : mWidth{width},
        mHeight{height},
        mSnake{ width, height },
        mFields{ initFieldWithWalls(width, height) },
        mRandomDevice{},
        mGenerator{ mRandomDevice() },
        mWidthDistribution{ 2, width - 3 },
        mHeightDistribution{ 2, height - 3 }
    {
    }

    void Board::reset()
    {
        mFields = initFieldWithWalls(mWidth, mHeight);
        mSnake = Snake{mWidth,mHeight};
    }

    void Board::placeFood()
    {
        for (;;) {
            auto x = mWidthDistribution(mGenerator);
            auto y = mHeightDistribution(mGenerator);

            if(mFields.at(y).at(x) == FieldType::empty){
                mFields.at(y).at(x) = FieldType::food;
                return;
            }
        }
    }

    void Board::updateSnakePosition()
    {
        auto snakeBody = mSnake.getBody();

        removeOldSnakePosition(snakeBody);
        addNewSnakePosition(snakeBody);
    }

    bool Board::snakeHitFood() const
    {
        auto pos = mSnake.getBody().at(0).pos;
        return mFields.at(pos.y).at(pos.x) == FieldType::food;
    }

    void Board::eatFood()
    {
        auto pos = mSnake.getBody()[0].pos;
        mFields.at(pos.y).at(pos.x) = FieldType::empty;
    }

    void Board::growSnake()
    {
        mSnake.grow();
    }

    bool Board::snakeHitWall() const
    {
        auto pos = mSnake.getBody()[0].pos;
        return mFields.at(pos.y).at(pos.x) == FieldType::wall;
    }

    bool Board::snakeHitSnake() const
    {
        auto pos = mSnake.getBody()[0].pos;
        return mFields.at(pos.y).at(pos.x) == FieldType::snakeSegment;
    }

    void Board::moveSnake(SnakeDirection snakeDirection)
    {
        switch (snakeDirection) {
        case SnakeDirection::right:
            mSnake.moveRight();
            break;

        case SnakeDirection::down:
            mSnake.moveDown();
            break;

        case SnakeDirection::left:
            mSnake.moveLeft();
            break;

        case SnakeDirection::up:
            mSnake.moveUp();
            break;
        }
    }

    void Board::debugPrintSnakeCoordinates()
    {
        auto body = mSnake.getBody();

        for (std::size_t i = 0; i < body.size(); ++i) {
            auto pos = body.at(i).pos;

            std::wcout << "nr:" << i << "x:" << pos.x
                       << "t" << "y:" << pos.y << "t";

            auto field = mFields.at(pos.y).at(pos.x);

            switch(field)
            {
            case FieldType::snakeHead:
                std::wcout << L"Headt";
                [[fallthrough]];
            case FieldType::snakeSegment:
                std::wcout << L"Bodyn";
                [[fallthrough]];
            default:
                std::wcout << L"    n";
            }
        }
    }

    FieldType Board::fieldTypeAt(std::size_t x, std::size_t y)
    {
        return mFields.at(y).at(x);
    }

    std::vector<std::vector<FieldType>> Board::initFieldWithWalls(
        std::size_t width, std::size_t height)
    {
        std::vector<FieldType> row(width, FieldType::empty);
        std::vector<std::vector<FieldType>> field(height, row);

        std::fill(field.at(0).begin(), field.at(0).end(), FieldType::wall);
        std::fill(field.at(field.size() - 1).begin(),
                  field.at(field.size() - 1).end(), FieldType::wall);

        for (auto it_row = field.begin() + 1;
             it_row < field.end() - 1; ++it_row) {
            (*it_row).at(0) = FieldType::wall;
            (*it_row).at(it_row->size() - 1) = FieldType::wall;
        }
        return field;
    }

    void Board::removeOldSnakePosition(const std::vector<SnakeSegment>& body)
    {
        for (const auto& snakeSegment : body) {
            auto prev = snakeSegment.prev;
            mFields.at(prev.y).at(prev.x) = FieldType::empty;
        }
    }

    void Board::addNewSnakePosition(const std::vector<SnakeSegment>& body)
    {
        auto first{ true };
        for (const auto& snakeSegment : body) {
            auto pos = snakeSegment.pos;

            if (first) {
                mFields.at(pos.y).at(pos.x) = FieldType::snakeHead;
                first = false;
            }
            else {
                mFields.at(pos.y).at(pos.x) = FieldType::snakeSegment;
            }
        }
    }


    std::wostream& operator<<(std::wostream& os, const Board& obj)
    {
        for (const auto& row : obj.mFields) {
            for (const auto& element : row) {

                switch(element){
                case FieldType::empty:
                    os << L' ';
                    break;
                case FieldType::wall:
                    os << L'#';
                    break;
                case FieldType::food:
                    os << L'*';
                    break;
                case FieldType::snakeHead:
                    os << L'@';
                    break;
                case FieldType::snakeSegment:
                    os << L'o';
                    break;
                }
            }
            os << 'n';
        }
        return os;
    }

}

Snake.h

#ifndef SNAKE_H
#define SNAKE_H

#include <vector>
#include <cstddef>

namespace snakeGame {

    struct Point {
        std::size_t x;
        std::size_t y;
    };

    struct SnakeSegment
    {
        Point pos{ 0 , 0 };
        Point prev{ pos };
    };

    class Snake
    {
    public:
        Snake(std::size_t boardWidth, std::size_t boardHeight);

        std::vector<SnakeSegment> getBody() const;

        void moveRight();
        void moveDown();
        void moveLeft();
        void moveUp();
        void grow();

    private:
        void safeCurrentPosToLastOfFirstElement();
        void moveRemainingElements();

        std::vector<SnakeSegment> mBody;
    };

    std::vector<SnakeSegment> initSnake(
        std::size_t fieldWidth, std::size_t fieldHeight);

}
#endif

Snake.cpp

#include "Snake.h"

namespace snakeGame {

    Snake::Snake(std::size_t fieldWidth, std::size_t fieldHeight)
        :mBody{ initSnake(fieldWidth, fieldHeight) }
    {
    }

    std::vector<SnakeSegment> Snake::getBody() const
    {
        return mBody;
    }


    void Snake::moveRight()
    {
        safeCurrentPosToLastOfFirstElement();
        ++mBody.at(0).pos.x;
        moveRemainingElements();
    }

    void Snake::moveDown()
    {
        safeCurrentPosToLastOfFirstElement();
        ++mBody.at(0).pos.y;
        moveRemainingElements();
    }

    void Snake::moveLeft()
    {
        safeCurrentPosToLastOfFirstElement();
        --mBody.at(0).pos.x;
        moveRemainingElements();
    }

    void Snake::moveUp()
    {
        safeCurrentPosToLastOfFirstElement();
        --mBody.at(0).pos.y;
        moveRemainingElements();
    }

    void Snake::grow()
    {
        mBody.push_back(SnakeSegment{
            {mBody.at(mBody.size() - 1).prev.x,
            mBody.at(mBody.size() - 1).prev.y}
        });
    }

    void Snake::safeCurrentPosToLastOfFirstElement()
    {
        mBody.at(0).prev.x = mBody.at(0).pos.x;
        mBody.at(0).prev.y = mBody.at(0).pos.y;
    }

    void Snake::moveRemainingElements()
    {
        for (std::size_t i = 1; i < mBody.size(); ++i) {
            mBody.at(i).prev.x = mBody.at(i).pos.x;
            mBody.at(i).prev.y = mBody.at(i).pos.y;
            mBody.at(i).pos.x = mBody.at(i - 1).prev.x;
            mBody.at(i).pos.y = mBody.at(i - 1).prev.y;
        }
    }


    std::vector<SnakeSegment> initSnake(
        std::size_t boardWidth, std::size_t boardHeight)
    {
        auto x = boardWidth / 2;
        auto y = boardHeight / 2;
        std::vector<SnakeSegment> body{
            SnakeSegment{ {x, y} },
            SnakeSegment{ {x - 1, y} },
        };
        return body;
    }

}

Snake_qt.pro

QT += widgets
CONFIG += c++17

SOURCES += 
    Board.cpp 
    Snake.cpp 
    SnakeBoard.cpp 
    SnakeWindow.cpp 
    main.cpp

HEADERS += 
    Board.h 
    Snake.h 
    SnakeBoard.h 
    SnakeWindow.h

FORMS += 
    SnakeWindow.ui

SnakeWindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>SnakeWindow</class>
 <widget class="QWidget" name="SnakeWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>771</width>
    <height>618</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Snake</string>
  </property>
  <property name="styleSheet">
   <string notr="true"/>
  </property>
  <layout class="QGridLayout" name="gridLayout">
   <item row="1" column="2" colspan="2">
    <widget class="QLCDNumber" name="delayLcd">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
       <horstretch>0</horstretch>
       <verstretch>1</verstretch>
      </sizepolicy>
     </property>
     <property name="font">
      <font>
       <pointsize>20</pointsize>
      </font>
     </property>
     <property name="styleSheet">
      <string notr="true">background-color: rgb(255, 255, 127);</string>
     </property>
     <property name="smallDecimalPoint">
      <bool>false</bool>
     </property>
     <property name="digitCount">
      <number>5</number>
     </property>
     <property name="mode">
      <enum>QLCDNumber::Dec</enum>
     </property>
     <property name="segmentStyle">
      <enum>QLCDNumber::Flat</enum>
     </property>
    </widget>
   </item>
   <item row="2" column="0" colspan="4">
    <widget class="SnakeBoard" name="snakeBoard">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
       <horstretch>0</horstretch>
       <verstretch>8</verstretch>
      </sizepolicy>
     </property>
     <property name="styleSheet">
      <string notr="true">background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 178, 102, 255), stop:0.55 rgba(235, 148, 61, 255), stop:0.98 rgba(0, 0, 0, 255), stop:1 rgba(0, 0, 0, 0));</string>
     </property>
     <property name="frameShape">
      <enum>QFrame::StyledPanel</enum>
     </property>
     <property name="frameShadow">
      <enum>QFrame::Raised</enum>
     </property>
    </widget>
   </item>
   <item row="3" column="3">
    <widget class="QPushButton" name="quitButton">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
       <horstretch>0</horstretch>
       <verstretch>1</verstretch>
      </sizepolicy>
     </property>
     <property name="font">
      <font>
       <pointsize>20</pointsize>
      </font>
     </property>
     <property name="focusPolicy">
      <enum>Qt::NoFocus</enum>
     </property>
     <property name="styleSheet">
      <string notr="true">
background-color: rgb(255, 170, 255);</string>
     </property>
     <property name="text">
      <string>Quit</string>
     </property>
    </widget>
   </item>
   <item row="0" column="0">
    <widget class="QLabel" name="scoreLabel">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
       <horstretch>0</horstretch>
       <verstretch>0</verstretch>
      </sizepolicy>
     </property>
     <property name="font">
      <font>
       <pointsize>20</pointsize>
       <weight>50</weight>
       <bold>false</bold>
      </font>
     </property>
     <property name="text">
      <string>Score</string>
     </property>
     <property name="alignment">
      <set>Qt::AlignCenter</set>
     </property>
    </widget>
   </item>
   <item row="1" column="0" colspan="2">
    <widget class="QLCDNumber" name="scoreLcd">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
       <horstretch>0</horstretch>
       <verstretch>1</verstretch>
      </sizepolicy>
     </property>
     <property name="font">
      <font>
       <pointsize>20</pointsize>
      </font>
     </property>
     <property name="styleSheet">
      <string notr="true">background-color: rgb(255, 255, 127);</string>
     </property>
     <property name="smallDecimalPoint">
      <bool>false</bool>
     </property>
     <property name="digitCount">
      <number>10</number>
     </property>
     <property name="segmentStyle">
      <enum>QLCDNumber::Flat</enum>
     </property>
    </widget>
   </item>
   <item row="0" column="2" colspan="2">
    <widget class="QLabel" name="delayLabel">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
       <horstretch>0</horstretch>
       <verstretch>0</verstretch>
      </sizepolicy>
     </property>
     <property name="font">
      <font>
       <pointsize>20</pointsize>
       <weight>50</weight>
       <bold>false</bold>
      </font>
     </property>
     <property name="text">
      <string>Delay in ms</string>
     </property>
     <property name="alignment">
      <set>Qt::AlignCenter</set>
     </property>
    </widget>
   </item>
   <item row="3" column="0">
    <widget class="QPushButton" name="startButton">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
       <horstretch>0</horstretch>
       <verstretch>1</verstretch>
      </sizepolicy>
     </property>
     <property name="font">
      <font>
       <pointsize>20</pointsize>
      </font>
     </property>
     <property name="focusPolicy">
      <enum>Qt::NoFocus</enum>
     </property>
     <property name="styleSheet">
      <string notr="true">background-color: rgb(85, 255, 0);</string>
     </property>
     <property name="text">
      <string>Start</string>
     </property>
    </widget>
   </item>
   <item row="3" column="1">
    <widget class="QPushButton" name="pauseButton">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
       <horstretch>0</horstretch>
       <verstretch>1</verstretch>
      </sizepolicy>
     </property>
     <property name="font">
      <font>
       <pointsize>20</pointsize>
      </font>
     </property>
     <property name="focusPolicy">
      <enum>Qt::NoFocus</enum>
     </property>
     <property name="styleSheet">
      <string notr="true">background-color: rgb(170, 255, 0);</string>
     </property>
     <property name="text">
      <string>Pause</string>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
 <customwidgets>
  <customwidget>
   <class>SnakeBoard</class>
   <extends>QFrame</extends>
   <header location="global">SnakeBoard.h</header>
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>


Get this bounty!!!