Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt window closes abruptally after changing dropdown option C++

Qt window closes abruptally after changing dropdown option C++

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 7 Posters 200 Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • W Offline
    W Offline
    weverson
    wrote last edited by
    #1

    Hi, I am new in Gt and am using it to learn and improve my skills in c++. I am develping a GUI to show database information. The window opens fine, but as soon as I try to change 'Source' on the dropdown menu, the window abruptally closes without showing errors.

    What I've tried:
    Add:

    blocksignals(true)
    code
    blocksignals(false)
    

    On the QObject::connect (connect signals),
    replaced:

    QObject::connect(sourceCombo, &QComboBox::currentTextChanged, window, updateCategories); 
    QObject::connect(categoryCombo, &QComboBox::currentTextChanged, window, updateSubjects);  
    QObject::connect(subjectCombo, &QComboBox::currentTextChanged, window, updateDetails);
    

    For:

    QObject::connect(sourceCombo, &QComboBox::currentTextChanged, sourceCombo, updateCategories); 
    QObject::connect(categoryCombo, &QComboBox::currentTextChanged, sourceCombo, updateSubjects);  
    QObject::connect(subjectCombo, &QComboBox::currentTextChanged, sourceCombo, updateDetails);
    

    dbwindow.h:

    #include <QWidget>      // Qt base class for all UI objects
    #include <QComboBox>    // Qt widget for drop-down lists
    #include <QVBoxLayout>  // Qt layout for vertical arrangement of widgets
    #include <QTextEdit>    // Qt for text edit field
    #include <QStringList>  // Qt container for lists of strings
    #include <QString>      // Qt string class
    #include <QLabel>       // Qt widget for text labels
    #include <QSet>         // Qt container for text labels
    #include <vector>       // Standard C++ vector container
    #include <iostream>
    
    
    struct Record {
        QString source;     // Source name
        QString category;   // Category name
        QString subject;    // Subject name
        QString details;    // Details text
    };
    
    // Function to create and show the main window with dependent dropdowns
    inline QWidget* createDbWindow(const std::vector<Record>& records) {
    
    
        try {
    
            QWidget* window = new QWidget;                  // Create the main window widget
            QVBoxLayout* layout = new QVBoxLayout(window);  // Create a vertical layout and set it for the window
    
            // Create dropdowns and text field
            QComboBox* sourceCombo = new QComboBox(window);         // Dropdown for source
            QComboBox* categoryCombo = new QComboBox(window);       // Dropdown for categories
            QComboBox* subjectCombo = new QComboBox(window);        // Dropdown for subjects
            QTextEdit* detailsEdit = new QTextEdit(window);         // Multi-line text field for details
            detailsEdit->setReadOnly(true);                         // Make details field read-only
            detailsEdit->setLineWrapMode(QTextEdit::WidgetWidth);   // Enable line wrapping to fit the widget width
    
            // Collect unique source from records
            QSet<QString> sources;               // Set to store unique brands
            for (const auto& rec : records) {
                sources.insert(rec.source);     // Insert brand into set
            }
    
            sourceCombo->addItems(QStringList(sources.begin(), sources.end()));     // Add sources to dropdown
            layout->addWidget(new QLabel("Source:", window));    // Add label for source
            layout->addWidget(sourceCombo);                     // Add source dropdown to layout
            layout->addWidget(new QLabel("Category:", window)); // Add label for category
            layout->addWidget(categoryCombo);                   // Add category dropdown to layout
            layout->addWidget(new QLabel("Subject:", window));  // Add label for subject
            layout->addWidget(subjectCombo);                    // Add subject dropdown to layout
            layout->addWidget(new QLabel("Details:", window));  // Add label for details
            layout->addWidget(detailsEdit);                     // Add details text field to layout
    
    
            // Helper function to update details field based on selected subject
            auto updateDetails = [&]() {
                QString selectedSource = sourceCombo->currentText();        // Get selected source
                QString selectedCategory = categoryCombo->currentText();    // Get selected category
                QString selectedSubject = subjectCombo->currentText();      // Get selected subject
                for (const auto& rec : records) {
                    if (rec.source == selectedSource && rec.category == selectedCategory && rec.subject == selectedSubject) {
                        detailsEdit->setText(rec.details);              // Set details text for matching record
                        return;
                    }
                }
                detailsEdit->clear();                               // Clear details if no match found
            };
    
            // Helper function to update subject options based on selected category
            auto updateSubjects = [&]() {
                subjectCombo->blockSignals(true);
                subjectCombo->clear();               // Clear subject dropdown
                QSet<QString> subjects;              // Set to store unique subjects
                QString selectedSource = sourceCombo->currentText();    // Get selected source
                QString selectedCategory = categoryCombo->currentText(); // Get selected category
                for (const auto& rec : records) {
                    if (rec.source == selectedSource && rec.category == selectedCategory)   // If record matches brand and category
                        subjects.insert(rec.subject);                   // Insert subject into set
                }
                subjectCombo->addItems(QStringList(subjects.begin(), subjects.end()));  // Add subjects to dropdown
                subjectCombo->blockSignals(false);  // Re-enable signals
                
                updateDetails();
            };
    
            // Helper function to update category options based on selected source
            auto updateCategories = [&] () {
                categoryCombo->blockSignals(true);
                categoryCombo->clear();                                // Clear category dropdown
                QSet<QString> categories;                              // Set to store unique categories
                QString selectedSource = sourceCombo->currentText();   // Get selected source
                for (const auto& rec: records) {
                    if (rec.source == selectedSource)                  // If record matches selected brand
                        categories.insert(rec.category);               // Insert category into set 
                }
                categoryCombo->addItems(QStringList(categories.begin(), categories.end()));  // Add categories to dropdown
                categoryCombo->blockSignals(false);  // Re-enable signals
                
                updateSubjects();
            };
    
            
            // Connect signals to update dropdowns and details when selection changes
            QObject::connect(sourceCombo, &QComboBox::currentTextChanged, window, updateCategories);        // Update categories when source changes
            QObject::connect(categoryCombo, &QComboBox::currentTextChanged, window, updateSubjects);        // Update subjects when category changes
            QObject::connect(subjectCombo, &QComboBox::currentTextChanged, window, updateDetails);          // Update details when subject changes
    
            // Initialize dropdowns with first source selected
            if (sourceCombo->count() > 0) {
                sourceCombo->setCurrentIndex(0);    // Select first source
                updateCategories();                 // Update categories for initial source
            }
    
            window->setLayout(layout);                  // Set the layout for the window
            window->setWindowTitle("Database Viewer");  // Set the window title
            window->resize(755, 378);                   // Set window to 20 x 10
            window->show();                             // Show the window on the screen
            return window;
    
        } catch (const std::exception& e) {
            std::cerr << e.what() << "\n";
        }
        
    }
    
    
    #endif  //!DBWINDOW_H
    

    dbacess.h:

    #ifndef DBCONNECTION_WINDOW_H
    #define DBCONNECTION_WINDOW_H
    
    #include <pqxx/pqxx>
    #include <iostream>
    #include <vector>
    #include <string>
    
    // Structure to store each database record
    struct DataEntry {
        // Fields for 'source', 'category', 'subject' and 'details' column 
        std::string source;
        std::string category;
        std::string subject;
        std::string details;
    };
    
    // Function to open a connection to the PostgreSQL database
    inline pqxx::connection openDatabase() {
        // Connection string with db parameters (host, port, dbname, user, password)
        std::string conn_str = "host=localhost port=5432 dbname=prescreen_diag_data_api user=postgres password=shakey-10";
        return pqxx::connection(conn_str);  // Return a new pqxx connection object
    }
    
    // Function to fetch data from db
    inline std::vector<DataEntry> fetchData(pqxx::connection& conn) {
        std::vector<DataEntry> data;    // Vector to store all fetched records
        try {
            pqxx::work txn(conn);   // Start a transaction on the connection
            // Execute teh SQL query to select the desired columns
            pqxx::result res = txn.exec("SELECT source, category, subject, details FROM diagnostic_assistance_db;");
            
            for (const auto& row : res) {
                // Create a new DataEntry struct
                DataEntry entry;
                // Assign each column value to the struct fields
                entry.source = row["source"].c_str();
                entry.category = row["category"].c_str();
                entry.subject = row["subject"].c_str();
                entry.details = row["details"].c_str();
                data.push_back(entry);  // Add the entry to the vector
            }
        } catch (const std::exception& e) {
            std::cerr << "Error: " << e.what() << std::endl;
        }
    
        return data;    // Return the vector with all records
    }
    
    #endif  //!DBCONNECTION_WINDOW_H
    
    

    main.cpp

    #include <QApplication>         // Qt application class
    #include <QStringList>          // For QStringList
    #include <pqxx/pqxx>
    #include "dbwindow.h"           // For createDbWindow function
    #include "dbaccess.h"           // For database access functions
    
    
    int main(int argc, char *argv[]) {
        try {
            QApplication app(argc, argv);   // Create the Qt application
    
            pqxx::connection conn = openDatabase();   // Open database connection
        
            std::vector<DataEntry> data = fetchData(conn);    // Fetch all data from the database
        
            std::vector<Record> records;      // Vector to store all records for the GUI
    
            for (const auto& entry : data) {
                // Convert each DataEntry from the database to a Record for GUI
                records.push_back({
                    QString::fromStdString(entry.source),       // Set source field
                    QString::fromStdString(entry.category),     // Set category field    
                    QString::fromStdString(entry.subject),      // Set subject field
                    QString::fromStdString(entry.details)       // Set details field
                });
            }
    
            QWidget* window = createDbWindow(records);  // Create and show the window with dependent dropdowns
        
            return app.exec();      // Start the Qt event loop
        } catch(const std::exception& e) {
            std::cerr << e.what() << "\n";
        }
    
        return 1;
    
    } 
    
    
    Pl45m4P Christian EhrlicherC 2 Replies Last reply
    0
    • Axel SpoerlA Offline
      Axel SpoerlA Offline
      Axel Spoerl
      Moderators
      wrote last edited by
      #2

      Hi @weverson and welcome to the Qt forum!
      Are you running this in a debugger?
      Maybe add debug statements in the updateSomething() lambdas.
      The debugger of Qt Creator shows you where the program aborts (if it does).
      My guess is that you still end up in an endless recursion and eventually the executable runs out of memory.
      But that's hard to say, because the code is rather busy.
      I'd recommend to drop all the try()ing.

      Software Engineer
      The Qt Company, Oslo

      1 Reply Last reply
      0
      • W Offline
        W Offline
        weverson
        wrote last edited by
        #3

        Hi Axel,
        Thank you very much for your help. I forgot to mention some important details.
        I am using VS code, so the debbuger is MSVC.
        Also, I am executing the code on cmd after creating the build files through Cmake.

        JonBJ 1 Reply Last reply
        0
        • W weverson

          Hi Axel,
          Thank you very much for your help. I forgot to mention some important details.
          I am using VS code, so the debbuger is MSVC.
          Also, I am executing the code on cmd after creating the build files through Cmake.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote last edited by JonB
          #4

          @weverson
          So you need to run/step through your code under the MSVC debugger. People don't know where in your hundreds of lines of code the issue lies. Not sure what your "Also, I am executing the code on cmd after creating the build files through Cmake." means, but as stated you need to run this under the debugger, not free running in some console window outside of debugger. Learning to debug with whatever debugger you use is the single most useful coding skill you will ever obtain, so it's worth spending some time to get familiar with it.

          1 Reply Last reply
          4
          • W weverson

            Hi, I am new in Gt and am using it to learn and improve my skills in c++. I am develping a GUI to show database information. The window opens fine, but as soon as I try to change 'Source' on the dropdown menu, the window abruptally closes without showing errors.

            What I've tried:
            Add:

            blocksignals(true)
            code
            blocksignals(false)
            

            On the QObject::connect (connect signals),
            replaced:

            QObject::connect(sourceCombo, &QComboBox::currentTextChanged, window, updateCategories); 
            QObject::connect(categoryCombo, &QComboBox::currentTextChanged, window, updateSubjects);  
            QObject::connect(subjectCombo, &QComboBox::currentTextChanged, window, updateDetails);
            

            For:

            QObject::connect(sourceCombo, &QComboBox::currentTextChanged, sourceCombo, updateCategories); 
            QObject::connect(categoryCombo, &QComboBox::currentTextChanged, sourceCombo, updateSubjects);  
            QObject::connect(subjectCombo, &QComboBox::currentTextChanged, sourceCombo, updateDetails);
            

            dbwindow.h:

            #include <QWidget>      // Qt base class for all UI objects
            #include <QComboBox>    // Qt widget for drop-down lists
            #include <QVBoxLayout>  // Qt layout for vertical arrangement of widgets
            #include <QTextEdit>    // Qt for text edit field
            #include <QStringList>  // Qt container for lists of strings
            #include <QString>      // Qt string class
            #include <QLabel>       // Qt widget for text labels
            #include <QSet>         // Qt container for text labels
            #include <vector>       // Standard C++ vector container
            #include <iostream>
            
            
            struct Record {
                QString source;     // Source name
                QString category;   // Category name
                QString subject;    // Subject name
                QString details;    // Details text
            };
            
            // Function to create and show the main window with dependent dropdowns
            inline QWidget* createDbWindow(const std::vector<Record>& records) {
            
            
                try {
            
                    QWidget* window = new QWidget;                  // Create the main window widget
                    QVBoxLayout* layout = new QVBoxLayout(window);  // Create a vertical layout and set it for the window
            
                    // Create dropdowns and text field
                    QComboBox* sourceCombo = new QComboBox(window);         // Dropdown for source
                    QComboBox* categoryCombo = new QComboBox(window);       // Dropdown for categories
                    QComboBox* subjectCombo = new QComboBox(window);        // Dropdown for subjects
                    QTextEdit* detailsEdit = new QTextEdit(window);         // Multi-line text field for details
                    detailsEdit->setReadOnly(true);                         // Make details field read-only
                    detailsEdit->setLineWrapMode(QTextEdit::WidgetWidth);   // Enable line wrapping to fit the widget width
            
                    // Collect unique source from records
                    QSet<QString> sources;               // Set to store unique brands
                    for (const auto& rec : records) {
                        sources.insert(rec.source);     // Insert brand into set
                    }
            
                    sourceCombo->addItems(QStringList(sources.begin(), sources.end()));     // Add sources to dropdown
                    layout->addWidget(new QLabel("Source:", window));    // Add label for source
                    layout->addWidget(sourceCombo);                     // Add source dropdown to layout
                    layout->addWidget(new QLabel("Category:", window)); // Add label for category
                    layout->addWidget(categoryCombo);                   // Add category dropdown to layout
                    layout->addWidget(new QLabel("Subject:", window));  // Add label for subject
                    layout->addWidget(subjectCombo);                    // Add subject dropdown to layout
                    layout->addWidget(new QLabel("Details:", window));  // Add label for details
                    layout->addWidget(detailsEdit);                     // Add details text field to layout
            
            
                    // Helper function to update details field based on selected subject
                    auto updateDetails = [&]() {
                        QString selectedSource = sourceCombo->currentText();        // Get selected source
                        QString selectedCategory = categoryCombo->currentText();    // Get selected category
                        QString selectedSubject = subjectCombo->currentText();      // Get selected subject
                        for (const auto& rec : records) {
                            if (rec.source == selectedSource && rec.category == selectedCategory && rec.subject == selectedSubject) {
                                detailsEdit->setText(rec.details);              // Set details text for matching record
                                return;
                            }
                        }
                        detailsEdit->clear();                               // Clear details if no match found
                    };
            
                    // Helper function to update subject options based on selected category
                    auto updateSubjects = [&]() {
                        subjectCombo->blockSignals(true);
                        subjectCombo->clear();               // Clear subject dropdown
                        QSet<QString> subjects;              // Set to store unique subjects
                        QString selectedSource = sourceCombo->currentText();    // Get selected source
                        QString selectedCategory = categoryCombo->currentText(); // Get selected category
                        for (const auto& rec : records) {
                            if (rec.source == selectedSource && rec.category == selectedCategory)   // If record matches brand and category
                                subjects.insert(rec.subject);                   // Insert subject into set
                        }
                        subjectCombo->addItems(QStringList(subjects.begin(), subjects.end()));  // Add subjects to dropdown
                        subjectCombo->blockSignals(false);  // Re-enable signals
                        
                        updateDetails();
                    };
            
                    // Helper function to update category options based on selected source
                    auto updateCategories = [&] () {
                        categoryCombo->blockSignals(true);
                        categoryCombo->clear();                                // Clear category dropdown
                        QSet<QString> categories;                              // Set to store unique categories
                        QString selectedSource = sourceCombo->currentText();   // Get selected source
                        for (const auto& rec: records) {
                            if (rec.source == selectedSource)                  // If record matches selected brand
                                categories.insert(rec.category);               // Insert category into set 
                        }
                        categoryCombo->addItems(QStringList(categories.begin(), categories.end()));  // Add categories to dropdown
                        categoryCombo->blockSignals(false);  // Re-enable signals
                        
                        updateSubjects();
                    };
            
                    
                    // Connect signals to update dropdowns and details when selection changes
                    QObject::connect(sourceCombo, &QComboBox::currentTextChanged, window, updateCategories);        // Update categories when source changes
                    QObject::connect(categoryCombo, &QComboBox::currentTextChanged, window, updateSubjects);        // Update subjects when category changes
                    QObject::connect(subjectCombo, &QComboBox::currentTextChanged, window, updateDetails);          // Update details when subject changes
            
                    // Initialize dropdowns with first source selected
                    if (sourceCombo->count() > 0) {
                        sourceCombo->setCurrentIndex(0);    // Select first source
                        updateCategories();                 // Update categories for initial source
                    }
            
                    window->setLayout(layout);                  // Set the layout for the window
                    window->setWindowTitle("Database Viewer");  // Set the window title
                    window->resize(755, 378);                   // Set window to 20 x 10
                    window->show();                             // Show the window on the screen
                    return window;
            
                } catch (const std::exception& e) {
                    std::cerr << e.what() << "\n";
                }
                
            }
            
            
            #endif  //!DBWINDOW_H
            

            dbacess.h:

            #ifndef DBCONNECTION_WINDOW_H
            #define DBCONNECTION_WINDOW_H
            
            #include <pqxx/pqxx>
            #include <iostream>
            #include <vector>
            #include <string>
            
            // Structure to store each database record
            struct DataEntry {
                // Fields for 'source', 'category', 'subject' and 'details' column 
                std::string source;
                std::string category;
                std::string subject;
                std::string details;
            };
            
            // Function to open a connection to the PostgreSQL database
            inline pqxx::connection openDatabase() {
                // Connection string with db parameters (host, port, dbname, user, password)
                std::string conn_str = "host=localhost port=5432 dbname=prescreen_diag_data_api user=postgres password=shakey-10";
                return pqxx::connection(conn_str);  // Return a new pqxx connection object
            }
            
            // Function to fetch data from db
            inline std::vector<DataEntry> fetchData(pqxx::connection& conn) {
                std::vector<DataEntry> data;    // Vector to store all fetched records
                try {
                    pqxx::work txn(conn);   // Start a transaction on the connection
                    // Execute teh SQL query to select the desired columns
                    pqxx::result res = txn.exec("SELECT source, category, subject, details FROM diagnostic_assistance_db;");
                    
                    for (const auto& row : res) {
                        // Create a new DataEntry struct
                        DataEntry entry;
                        // Assign each column value to the struct fields
                        entry.source = row["source"].c_str();
                        entry.category = row["category"].c_str();
                        entry.subject = row["subject"].c_str();
                        entry.details = row["details"].c_str();
                        data.push_back(entry);  // Add the entry to the vector
                    }
                } catch (const std::exception& e) {
                    std::cerr << "Error: " << e.what() << std::endl;
                }
            
                return data;    // Return the vector with all records
            }
            
            #endif  //!DBCONNECTION_WINDOW_H
            
            

            main.cpp

            #include <QApplication>         // Qt application class
            #include <QStringList>          // For QStringList
            #include <pqxx/pqxx>
            #include "dbwindow.h"           // For createDbWindow function
            #include "dbaccess.h"           // For database access functions
            
            
            int main(int argc, char *argv[]) {
                try {
                    QApplication app(argc, argv);   // Create the Qt application
            
                    pqxx::connection conn = openDatabase();   // Open database connection
                
                    std::vector<DataEntry> data = fetchData(conn);    // Fetch all data from the database
                
                    std::vector<Record> records;      // Vector to store all records for the GUI
            
                    for (const auto& entry : data) {
                        // Convert each DataEntry from the database to a Record for GUI
                        records.push_back({
                            QString::fromStdString(entry.source),       // Set source field
                            QString::fromStdString(entry.category),     // Set category field    
                            QString::fromStdString(entry.subject),      // Set subject field
                            QString::fromStdString(entry.details)       // Set details field
                        });
                    }
            
                    QWidget* window = createDbWindow(records);  // Create and show the window with dependent dropdowns
                
                    return app.exec();      // Start the Qt event loop
                } catch(const std::exception& e) {
                    std::cerr << e.what() << "\n";
                }
            
                return 1;
            
            } 
            
            
            Pl45m4P Offline
            Pl45m4P Offline
            Pl45m4
            wrote last edited by
            #5

            @weverson

            The way the code is commented looks like it's fully AI generated/assisted.
            So why you don't tell Copilot in VSCode to fix the issue? /s


            If debugging is the process of removing software bugs, then programming must be the process of putting them in.

            ~E. W. Dijkstra

            S 1 Reply Last reply
            1
            • Pl45m4P Pl45m4

              @weverson

              The way the code is commented looks like it's fully AI generated/assisted.
              So why you don't tell Copilot in VSCode to fix the issue? /s

              S Offline
              S Offline
              SimonSchroeder
              wrote last edited by
              #6

              @Pl45m4 said in Qt window closes abruptally after changing dropdown option C++:

              The way the code is commented looks like it's fully AI generated/assisted.

              Ah, that would also explain why the code looks so non-idiomatic. Perhaps one needs to tell AI to write idiomatic Qt code to get proper results.

              (Why I don't think it is idiomatic: 1) try/catch everywhere. 2) Inline functions in headers (at least put them into separate .cpp files). 3) Not using a class derived from QWidget for DbWindow. 4) And consequently using lambdas instead of slots of the missing DbWindow class.)

              JonBJ Pl45m4P 2 Replies Last reply
              1
              • S SimonSchroeder

                @Pl45m4 said in Qt window closes abruptally after changing dropdown option C++:

                The way the code is commented looks like it's fully AI generated/assisted.

                Ah, that would also explain why the code looks so non-idiomatic. Perhaps one needs to tell AI to write idiomatic Qt code to get proper results.

                (Why I don't think it is idiomatic: 1) try/catch everywhere. 2) Inline functions in headers (at least put them into separate .cpp files). 3) Not using a class derived from QWidget for DbWindow. 4) And consequently using lambdas instead of slots of the missing DbWindow class.)

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote last edited by
                #7

                @SimonSchroeder
                Interesting. What is the point of declaring a 50+ line function, to create a window which is probably called once, inline? I suppose there is no point asking what the point is. ;-)

                1 Reply Last reply
                1
                • J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote last edited by
                  #8

                  inline is a suggestion anyway, like speed limits :P


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  1 Reply Last reply
                  0
                  • S SimonSchroeder

                    @Pl45m4 said in Qt window closes abruptally after changing dropdown option C++:

                    The way the code is commented looks like it's fully AI generated/assisted.

                    Ah, that would also explain why the code looks so non-idiomatic. Perhaps one needs to tell AI to write idiomatic Qt code to get proper results.

                    (Why I don't think it is idiomatic: 1) try/catch everywhere. 2) Inline functions in headers (at least put them into separate .cpp files). 3) Not using a class derived from QWidget for DbWindow. 4) And consequently using lambdas instead of slots of the missing DbWindow class.)

                    Pl45m4P Offline
                    Pl45m4P Offline
                    Pl45m4
                    wrote last edited by Pl45m4
                    #9

                    @SimonSchroeder

                    But seriously, who would comment on every single header/include and give an explanation what is included? And why? Except AI?

                    What sane human does this? :DD

                    #include <QWidget>      // Qt base class for all UI objects
                    #include <QComboBox>    // Qt widget for drop-down lists
                    #include <QVBoxLayout>  // Qt layout for vertical arrangement of widgets
                    #include <QTextEdit>    // Qt for text edit field
                    #include <QStringList>  // Qt container for lists of strings
                    #include <QString>      // Qt string class
                    #include <QLabel>       // Qt widget for text labels
                    #include <QSet>         // Qt container for text labels
                    #include <vector>       // Standard C++ vector container
                    

                    @weverson
                    And to solve the issue debugging the code is the best method to find the spot where it crashes.
                    I assume it segfaults or something, if the program suddenly closes while changing the values of the combobox


                    If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                    ~E. W. Dijkstra

                    1 Reply Last reply
                    0
                    • W Offline
                      W Offline
                      weverson
                      wrote last edited by
                      #10

                      Hi guys,
                      Thank you very much for your help. Just want to clarify something here. I am using AI to generate this code because I am a beginner and really want to learn how to use Qt and program in C++. As the learning process in programming languages envolves typing millions of code lines, this is the way I found out to learn and the Copilot is used to help me understanding how things, but the Qt documentation is opened in of the windows of my browser, meaning I do not simply type AI code generated without trying to understand the documentation. But one of the dificults I've faced is understading Qt documentation. It is quite hard to understand, very different compared to pandas from Python, which I've used every single day and started my programming journey. But I will not give up regardless whether or not it is hard, I will learn and work hard to become the best developer.

                      @JonB ,
                      In regards to executing the .exe on window terminal, what I meant is that I am executing it because I had previous errors executing on power shell from vs code and was instructed to run this way to fix the errors and then they were fixed. I am still getting used with concepts and therms from dev world, but I understand this is normal.

                      @SimonSchroeder,
                      I requested the AI to comment every single line of this code to help me understand each class. If you can focus on help me and ignore the way/who gave me this code, I would appreciate it. Or you guys may give me some suggestions on how to learn programming using Qt.

                      Thanks!

                      1 Reply Last reply
                      0
                      • W weverson

                        Hi, I am new in Gt and am using it to learn and improve my skills in c++. I am develping a GUI to show database information. The window opens fine, but as soon as I try to change 'Source' on the dropdown menu, the window abruptally closes without showing errors.

                        What I've tried:
                        Add:

                        blocksignals(true)
                        code
                        blocksignals(false)
                        

                        On the QObject::connect (connect signals),
                        replaced:

                        QObject::connect(sourceCombo, &QComboBox::currentTextChanged, window, updateCategories); 
                        QObject::connect(categoryCombo, &QComboBox::currentTextChanged, window, updateSubjects);  
                        QObject::connect(subjectCombo, &QComboBox::currentTextChanged, window, updateDetails);
                        

                        For:

                        QObject::connect(sourceCombo, &QComboBox::currentTextChanged, sourceCombo, updateCategories); 
                        QObject::connect(categoryCombo, &QComboBox::currentTextChanged, sourceCombo, updateSubjects);  
                        QObject::connect(subjectCombo, &QComboBox::currentTextChanged, sourceCombo, updateDetails);
                        

                        dbwindow.h:

                        #include <QWidget>      // Qt base class for all UI objects
                        #include <QComboBox>    // Qt widget for drop-down lists
                        #include <QVBoxLayout>  // Qt layout for vertical arrangement of widgets
                        #include <QTextEdit>    // Qt for text edit field
                        #include <QStringList>  // Qt container for lists of strings
                        #include <QString>      // Qt string class
                        #include <QLabel>       // Qt widget for text labels
                        #include <QSet>         // Qt container for text labels
                        #include <vector>       // Standard C++ vector container
                        #include <iostream>
                        
                        
                        struct Record {
                            QString source;     // Source name
                            QString category;   // Category name
                            QString subject;    // Subject name
                            QString details;    // Details text
                        };
                        
                        // Function to create and show the main window with dependent dropdowns
                        inline QWidget* createDbWindow(const std::vector<Record>& records) {
                        
                        
                            try {
                        
                                QWidget* window = new QWidget;                  // Create the main window widget
                                QVBoxLayout* layout = new QVBoxLayout(window);  // Create a vertical layout and set it for the window
                        
                                // Create dropdowns and text field
                                QComboBox* sourceCombo = new QComboBox(window);         // Dropdown for source
                                QComboBox* categoryCombo = new QComboBox(window);       // Dropdown for categories
                                QComboBox* subjectCombo = new QComboBox(window);        // Dropdown for subjects
                                QTextEdit* detailsEdit = new QTextEdit(window);         // Multi-line text field for details
                                detailsEdit->setReadOnly(true);                         // Make details field read-only
                                detailsEdit->setLineWrapMode(QTextEdit::WidgetWidth);   // Enable line wrapping to fit the widget width
                        
                                // Collect unique source from records
                                QSet<QString> sources;               // Set to store unique brands
                                for (const auto& rec : records) {
                                    sources.insert(rec.source);     // Insert brand into set
                                }
                        
                                sourceCombo->addItems(QStringList(sources.begin(), sources.end()));     // Add sources to dropdown
                                layout->addWidget(new QLabel("Source:", window));    // Add label for source
                                layout->addWidget(sourceCombo);                     // Add source dropdown to layout
                                layout->addWidget(new QLabel("Category:", window)); // Add label for category
                                layout->addWidget(categoryCombo);                   // Add category dropdown to layout
                                layout->addWidget(new QLabel("Subject:", window));  // Add label for subject
                                layout->addWidget(subjectCombo);                    // Add subject dropdown to layout
                                layout->addWidget(new QLabel("Details:", window));  // Add label for details
                                layout->addWidget(detailsEdit);                     // Add details text field to layout
                        
                        
                                // Helper function to update details field based on selected subject
                                auto updateDetails = [&]() {
                                    QString selectedSource = sourceCombo->currentText();        // Get selected source
                                    QString selectedCategory = categoryCombo->currentText();    // Get selected category
                                    QString selectedSubject = subjectCombo->currentText();      // Get selected subject
                                    for (const auto& rec : records) {
                                        if (rec.source == selectedSource && rec.category == selectedCategory && rec.subject == selectedSubject) {
                                            detailsEdit->setText(rec.details);              // Set details text for matching record
                                            return;
                                        }
                                    }
                                    detailsEdit->clear();                               // Clear details if no match found
                                };
                        
                                // Helper function to update subject options based on selected category
                                auto updateSubjects = [&]() {
                                    subjectCombo->blockSignals(true);
                                    subjectCombo->clear();               // Clear subject dropdown
                                    QSet<QString> subjects;              // Set to store unique subjects
                                    QString selectedSource = sourceCombo->currentText();    // Get selected source
                                    QString selectedCategory = categoryCombo->currentText(); // Get selected category
                                    for (const auto& rec : records) {
                                        if (rec.source == selectedSource && rec.category == selectedCategory)   // If record matches brand and category
                                            subjects.insert(rec.subject);                   // Insert subject into set
                                    }
                                    subjectCombo->addItems(QStringList(subjects.begin(), subjects.end()));  // Add subjects to dropdown
                                    subjectCombo->blockSignals(false);  // Re-enable signals
                                    
                                    updateDetails();
                                };
                        
                                // Helper function to update category options based on selected source
                                auto updateCategories = [&] () {
                                    categoryCombo->blockSignals(true);
                                    categoryCombo->clear();                                // Clear category dropdown
                                    QSet<QString> categories;                              // Set to store unique categories
                                    QString selectedSource = sourceCombo->currentText();   // Get selected source
                                    for (const auto& rec: records) {
                                        if (rec.source == selectedSource)                  // If record matches selected brand
                                            categories.insert(rec.category);               // Insert category into set 
                                    }
                                    categoryCombo->addItems(QStringList(categories.begin(), categories.end()));  // Add categories to dropdown
                                    categoryCombo->blockSignals(false);  // Re-enable signals
                                    
                                    updateSubjects();
                                };
                        
                                
                                // Connect signals to update dropdowns and details when selection changes
                                QObject::connect(sourceCombo, &QComboBox::currentTextChanged, window, updateCategories);        // Update categories when source changes
                                QObject::connect(categoryCombo, &QComboBox::currentTextChanged, window, updateSubjects);        // Update subjects when category changes
                                QObject::connect(subjectCombo, &QComboBox::currentTextChanged, window, updateDetails);          // Update details when subject changes
                        
                                // Initialize dropdowns with first source selected
                                if (sourceCombo->count() > 0) {
                                    sourceCombo->setCurrentIndex(0);    // Select first source
                                    updateCategories();                 // Update categories for initial source
                                }
                        
                                window->setLayout(layout);                  // Set the layout for the window
                                window->setWindowTitle("Database Viewer");  // Set the window title
                                window->resize(755, 378);                   // Set window to 20 x 10
                                window->show();                             // Show the window on the screen
                                return window;
                        
                            } catch (const std::exception& e) {
                                std::cerr << e.what() << "\n";
                            }
                            
                        }
                        
                        
                        #endif  //!DBWINDOW_H
                        

                        dbacess.h:

                        #ifndef DBCONNECTION_WINDOW_H
                        #define DBCONNECTION_WINDOW_H
                        
                        #include <pqxx/pqxx>
                        #include <iostream>
                        #include <vector>
                        #include <string>
                        
                        // Structure to store each database record
                        struct DataEntry {
                            // Fields for 'source', 'category', 'subject' and 'details' column 
                            std::string source;
                            std::string category;
                            std::string subject;
                            std::string details;
                        };
                        
                        // Function to open a connection to the PostgreSQL database
                        inline pqxx::connection openDatabase() {
                            // Connection string with db parameters (host, port, dbname, user, password)
                            std::string conn_str = "host=localhost port=5432 dbname=prescreen_diag_data_api user=postgres password=shakey-10";
                            return pqxx::connection(conn_str);  // Return a new pqxx connection object
                        }
                        
                        // Function to fetch data from db
                        inline std::vector<DataEntry> fetchData(pqxx::connection& conn) {
                            std::vector<DataEntry> data;    // Vector to store all fetched records
                            try {
                                pqxx::work txn(conn);   // Start a transaction on the connection
                                // Execute teh SQL query to select the desired columns
                                pqxx::result res = txn.exec("SELECT source, category, subject, details FROM diagnostic_assistance_db;");
                                
                                for (const auto& row : res) {
                                    // Create a new DataEntry struct
                                    DataEntry entry;
                                    // Assign each column value to the struct fields
                                    entry.source = row["source"].c_str();
                                    entry.category = row["category"].c_str();
                                    entry.subject = row["subject"].c_str();
                                    entry.details = row["details"].c_str();
                                    data.push_back(entry);  // Add the entry to the vector
                                }
                            } catch (const std::exception& e) {
                                std::cerr << "Error: " << e.what() << std::endl;
                            }
                        
                            return data;    // Return the vector with all records
                        }
                        
                        #endif  //!DBCONNECTION_WINDOW_H
                        
                        

                        main.cpp

                        #include <QApplication>         // Qt application class
                        #include <QStringList>          // For QStringList
                        #include <pqxx/pqxx>
                        #include "dbwindow.h"           // For createDbWindow function
                        #include "dbaccess.h"           // For database access functions
                        
                        
                        int main(int argc, char *argv[]) {
                            try {
                                QApplication app(argc, argv);   // Create the Qt application
                        
                                pqxx::connection conn = openDatabase();   // Open database connection
                            
                                std::vector<DataEntry> data = fetchData(conn);    // Fetch all data from the database
                            
                                std::vector<Record> records;      // Vector to store all records for the GUI
                        
                                for (const auto& entry : data) {
                                    // Convert each DataEntry from the database to a Record for GUI
                                    records.push_back({
                                        QString::fromStdString(entry.source),       // Set source field
                                        QString::fromStdString(entry.category),     // Set category field    
                                        QString::fromStdString(entry.subject),      // Set subject field
                                        QString::fromStdString(entry.details)       // Set details field
                                    });
                                }
                        
                                QWidget* window = createDbWindow(records);  // Create and show the window with dependent dropdowns
                            
                                return app.exec();      // Start the Qt event loop
                            } catch(const std::exception& e) {
                                std::cerr << e.what() << "\n";
                            }
                        
                            return 1;
                        
                        } 
                        
                        
                        Christian EhrlicherC Offline
                        Christian EhrlicherC Offline
                        Christian Ehrlicher
                        Lifetime Qt Champion
                        wrote last edited by Christian Ehrlicher
                        #11

                        @weverson said in Qt window closes abruptally after changing dropdown option C++:

                        {
                            ...
                            QComboBox* sourceCombo = new QComboBox(window);
                            ....
                            auto updateDetails = [&]() {
                                QString selectedSource = sourceCombo->currentText();        // Get selected source
                                ....
                            };
                        }
                        

                        How should this work? sourceCombo is a local variable which goes out of scope since it is only passed as reference to the lambda.

                        Nice example on why AI is dumb as bread.

                        @weverson : when you really want to learn C++ take a good book or online course and don't use any ai stuff until you know what you're doing.

                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                        Visit the Qt Academy at https://academy.qt.io/catalog

                        1 Reply Last reply
                        1

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved