Qt window closes abruptally after changing dropdown option C++
-
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_Hdbacess.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_Hmain.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; } -
Hi @weverson and welcome to the Qt forum!
Are you running this in a debugger?
Maybe add debug statements in theupdateSomething()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. -
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.@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. -
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_Hdbacess.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_Hmain.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; } -
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@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/catcheverywhere. 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.) -
@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/catcheverywhere. 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.)@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. ;-) -
inline is a suggestion anyway, like speed limits :P
-
@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/catcheverywhere. 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.)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 -
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!
-
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_Hdbacess.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_Hmain.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; }@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.