Evgenii Legotckoi
Evgenii Legotckoi1. Dezember 2019 14:22

Qt/C++ - Tutorial 090. So erstellen Sie einen Lerndialog mit Hervorhebung von Widgets im Programm

Ich schlage vor, eine kleine Anwendung zu studieren, in der ein Dialogfeld erstellt wird, dank dessen der Benutzer die Funktionalität Ihres Programms kennenlernen und Schritt für Schritt erklären kann, welches Software-Widget wofür verantwortlich ist.

Um eine solche Funktionalität zu implementieren, muss ein Anwendungsfenster erstellt werden, in dem sich die Schaltflächen "Vorheriges Widget", "Nächstes Widget", "Fenster schließen" befinden. Vor dem Start werden Widgets in der Reihenfolge an dieses Fenster übergeben, in der sie dem Benutzer in Ihrem Programm angezeigt werden sollen, sowie Textnachrichten, die die Widgets beschreiben.

Das Programm wird wie folgt aussehen:


Einführung

Wie wir vereinbart haben, werden wir einen Trainings -Dialog erstellen, der eine Reihe von Widgets akzeptiert, über die wir sprechen müssen.
In diesem Fall wird das aktuelle Widget durch Umdefinieren seines Stils hervorgehoben, dh es wird ein roter Widget-Rahmen gesetzt.
Ich muss gleich sagen, dass die Neudefinition von Stilen über Stylesheet eine vollständige Neudefinition der Stile einiger Widgets für einige Plattformen nach sich ziehen kann, daher ist es besser, einen vollständig benutzerdefinierten Anwendungsstil zu erstellen oder Widgets mit einer Überschreibung des paintEvent -Methode. In jedem Fall müssen Sie für ein schöneres Highlight viel Arbeit in das Styling der Anwendung investieren, aber für die Zwecke des Tutorials werde ich nur eine minimale Neudefinition von Stilen zeigen.

TutorialDialog

Der Qt-Grafikdesigner hat einen Dialog, um nützlichen Code sauber zu halten. Das heißt, der Dialog selbst wird mithilfe der Benutzeroberfläche gebildet. Es wird so aussehen. Den Programmcode erhalten Sie im EVILEG-Beispielrepository am Ende des Artikels.

TutorialDialog.h

In der Header-Datei des Dialogfelds müssen Sie die TutorialInfo -Struktur verwenden, die einen Zeiger auf das Widget sowie seine Beschreibung speichert.
Wir brauchen auch eine Variable, die den alten Stil des aktuellen Widgets und den Index des aktuellen Widgets speichert.

#ifndef TUTORIALDIALOG_H
#define TUTORIALDIALOG_H

#include <QDialog>

namespace Ui {
class TutorialDialog;
}

class TutorialDialog : public QDialog
{
    Q_OBJECT

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

    // add widget and text information about this widget to tutorial dialog
    void addWidgetToTutorial(QWidget* widget, const QString& text);

private:
    void onPreviousButtonClicked(); // slot which reacts on click of previous button
    void onNextButtonClicked();     // slot which reacts on click of next button
    void updateButtonsEnabled();    // update actual enabled status of buttons
    void returnOldStyle();          // return old style to widget, which was highlighted
    void setTextAndStyle();         // set text information to tutorial dialog and set highlight style to widget

    Ui::TutorialDialog *ui;

    // This structure contains text information aboout some widget
    struct TutorialInfo
    {
        QWidget* widget;
        QString text;
    };

    // highlight style
    const QString HIGHLIGHT_STYLE {"border: 1px solid red"};
    QVector<TutorialInfo> m_infoItems;      // vector of widgets in tutorial
    int m_currentTutorialInfoIndex {-1};    // index of current highlighted widget
    QString m_oldStyleOfWidget;             // old widget style
};

#endif // TUTORIALDIALOG_H

TutorialDialog.cpp

#include "TutorialDialog.h"
#include "ui_TutorialDialog.h"

#include <QDebug>

TutorialDialog::TutorialDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::TutorialDialog)
{
    ui->setupUi(this);
    setModal(true);                 // this dialog should be modal
    setWindowFlags(Qt::Window);     // but it doesn`t create shadow on mainwindow

    connect(ui->closeButton, &QPushButton::clicked, this, &TutorialDialog::close);
    connect(ui->previousButton, &QPushButton::clicked, this, &TutorialDialog::onPreviousButtonClicked);
    connect(ui->nextButton, &QPushButton::clicked, this, &TutorialDialog::onNextButtonClicked);

    updateButtonsEnabled();
}

TutorialDialog::~TutorialDialog()
{
    // When dialog was destrcucted, we should set up old style to current widget
    returnOldStyle();
    delete ui;
}

void TutorialDialog::addWidgetToTutorial(QWidget* widget, const QString& text)
{
    if (m_infoItems.empty())
    {
        m_currentTutorialInfoIndex = 0;
    }

    m_infoItems.push_back({widget, text});
    updateButtonsEnabled();

    if (m_infoItems.size() == 1)
    {
        setTextAndStyle();
    }
}

void TutorialDialog::onPreviousButtonClicked()
{
    returnOldStyle();
    --m_currentTutorialInfoIndex;
    setTextAndStyle();
    updateButtonsEnabled();
}

void TutorialDialog::onNextButtonClicked()
{
    returnOldStyle();
    ++m_currentTutorialInfoIndex;
    setTextAndStyle();
    updateButtonsEnabled();
}

void TutorialDialog::updateButtonsEnabled()
{
    ui->previousButton->setEnabled(m_currentTutorialInfoIndex != -1 && m_currentTutorialInfoIndex > 0);
    ui->nextButton->setEnabled(m_currentTutorialInfoIndex != -1 && m_currentTutorialInfoIndex < m_infoItems.size() - 1);
}

void TutorialDialog::returnOldStyle()
{
    if (m_currentTutorialInfoIndex != -1)
    {
        m_infoItems[m_currentTutorialInfoIndex].widget->setStyleSheet(m_oldStyleOfWidget);
    }
}

void TutorialDialog::setTextAndStyle()
{
    ui->textBrowser->setText(m_infoItems[m_currentTutorialInfoIndex].text);
    m_oldStyleOfWidget = m_infoItems[m_currentTutorialInfoIndex].widget->styleSheet();
    m_infoItems[m_currentTutorialInfoIndex].widget->setStyleSheet(HIGHLIGHT_STYLE);
}

Hauptfenster

Und dann müssen wir diesen Dialog im Dialog-Startslot des Lernprogramms erstellen und dem Dialog auch Widgets und Informationen zu diesen Widgets hinzufügen.

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    void onStartTutorialButtonClicked();

    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

MainWindow.cpp

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "TutorialDialog.h"
#include "TutorialDialog.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->startTutorialButton, &QPushButton::clicked, this, &MainWindow::onStartTutorialButtonClicked);
}

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

void MainWindow::onStartTutorialButtonClicked()
{
    TutorialDialog tutorialDialog;  // Create tutorial dialog

    // Add widgets to tutorial dialog
    tutorialDialog.addWidgetToTutorial(ui->projectStructureTreeView, tr("This is project structure"));
    tutorialDialog.addWidgetToTutorial(ui->createProjectButton, tr("Create new project using this button"));
    tutorialDialog.addWidgetToTutorial(ui->openProjectButton, tr("Open your project using this button"));
    tutorialDialog.addWidgetToTutorial(ui->infoWidget, tr("Here You will see some information about objects in your project"));

    // Start tutorial dialog
    tutorialDialog.exec();
}

Fazit

Um die Idee eines Lernfensters zu entwickeln, können Sie entweder die Vererbung aller im Programm verwendeten Widgets verwenden, indem Sie die Methode paintEvent überschreiben, um den ausgewählten Rahmen hinzuzufügen und zu entfernen, oder alle von Widgets verwendeten Stile damit vollständig neu definieren dass beim Setzen von stylesheet jene Styles, die nicht gebrochen werden sollen.

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

Kommentare

Nur autorisierte Benutzer können Kommentare posten.
Bitte Anmelden oder Registrieren
Letzte Kommentare
ИМ
Игорь Максимов5. Oktober 2024 14:51
Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55. Juli 2024 18:02
QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr9. Februar 2024 02:43
Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25. Dezember 2023 18:30
Boost - statisches Verknüpfen im CMake-Projekt unter Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
Jetzt im Forum diskutieren
J
JacobFib17. Oktober 2024 10:27
добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
JW
Jhon Wick1. Oktober 2024 22:52
Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
КГ
Кирилл Гусарев27. September 2024 16:09
Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
F
Fynjy22. Juli 2024 11:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

Folgen Sie uns in sozialen Netzwerken