Back to your original post - there is a better way to abstract this than to require your report window to decipher which button in some other, completely unrelated window was the one that was clicked. What happens if you want to add to your UI the ability to change reports based on a menu action or a combobox selection? Your logic to change reports based on button clicks falls apart completely because there is no button.
So what I would do is this:
1 - in your report window, implement a slot that takes as an argument some type of ID - an integer, enum value, string, whatever - that uniquely identifies the report you want to produce
2 - in the windows that hold your buttons, implement slots for each of the button clicked() signals.
3 - in those same windows, implement signals the send an ID value when emitted. In the button click handling slots, emit the signal with the appropriate id value
4 - connect the signals in the button windows to the slot in the report window.
Something like this:
// ButtonWindow.h
signals:
void reportSelected( int reportId );
protected slots:
void onButtonClicked();
// ButtonWindow.cpp
ButtonWindow
::ButtonWindow( QWidget * parent
) : // base class constructor
{
ui.setupUi( this );
connect( ui.button, &QPushButton::clicked, this, &ButtonWindow::onButtonClicked );
}
void ButtonWindow::onButtonClicked()
{
emit reportSelected( Report1 ); // "Report1" is a value from an enum, for example
}
// ReportWindow.h
public slots:
void onReportSelected( int reportId );
// ReportWindow.cpp
void ReportWindow::onReportSelected( int reportId )
{
switch reportId:
{
case Report1:
// format a Report1 type report...
break;
// ...
}
}
// MainWindow.cpp
MainWindow
::MainWindow( QWidget * parent
){
ui.setupUi( this );
// create report window
ReportWindow * pRW = new ReportWindow( this );
// create button windows
ButtonWindow * pBW = new ButtonWindow( this );
// connect button window to report window
connect( pBW, &ButtonWindow::reportSelected, pRW, &ReportWindow::onReportSelected );
}
// ButtonWindow.h
signals:
void reportSelected( int reportId );
protected slots:
void onButtonClicked();
// ButtonWindow.cpp
ButtonWindow::ButtonWindow( QWidget * parent )
: // base class constructor
{
ui.setupUi( this );
connect( ui.button, &QPushButton::clicked, this, &ButtonWindow::onButtonClicked );
}
void ButtonWindow::onButtonClicked()
{
emit reportSelected( Report1 ); // "Report1" is a value from an enum, for example
}
// ReportWindow.h
public slots:
void onReportSelected( int reportId );
// ReportWindow.cpp
void ReportWindow::onReportSelected( int reportId )
{
switch reportId:
{
case Report1:
// format a Report1 type report...
break;
// ...
}
}
// MainWindow.cpp
MainWindow::MainWindow( QWidget * parent )
: QMainWindow( parent )
{
ui.setupUi( this );
// create report window
ReportWindow * pRW = new ReportWindow( this );
// create button windows
ButtonWindow * pBW = new ButtonWindow( this );
// connect button window to report window
connect( pBW, &ButtonWindow::reportSelected, pRW, &ReportWindow::onReportSelected );
}
To copy to clipboard, switch view to plain text mode
The nice thing about this, even though it uses more signal and slot overhead, is that it completely decouples buttons from reports. The report window doesn't know how the signal to change the report type got generated, all it knows is that it should change the type to whatever was requested. Likewise, the buttons don't know that they are changing a report format, they just know they might be telling something, somewhere, that a new report ID has been chosen.
So this mean you can send a signal with a report ID from anywhere in your UI - a menu, combobox, push button, radio button, whatever - so long as the signal that the control emits is connected to a slot that in turn emits a signal with a report ID. Connect that signal to the report window's slot, and you have added a new capability to your program with no change in the architecture.
Bookmarks