[c++] opening window B by clicking a button on window A
-
I have 2 windows, BusRegistration and start ( The main window )
I open start window simply by
int main(int argc, char *argv[]) { QApplication a(argc, argv); start w; w.show(); return a.exec(); }
My goal is to show BusRegistration window by clicking on a button from start window but to do that I need a Bus object that the button function from start.cpp can access .
Declaring the bus object inside start.cpp results in an error.
The following code shows the bus window for a brief until it's deallocated because the function terminates so it doesn't work eithervoid start::on_BusRegistration_clicked() { BusRegister bus; bus.show(); }
Apologies for the basic question but I couldn't find an appropriate solution for this.
-
This is generic C++ object lifetime knowledge.
Allocate the BusRegister object on the heap, not the stack.
At its simplest:void start::on_BusRegistration_clicked() { BusRegister *bus = new BusRegister(this); // if you want the object deleted when the visible widget is closed then bus->setAttribute(Qt::WA_DeleteOnClose); // otherwise you will create new one for each button click and keep them all. // They will all be deleted with the `start` object because of QObject parenting. bus->show(); }
If that window will be opened and closed a lot, or you need to access it outside this slot then you may store the pointer as a member variable in the launching
start
object:// modify the header private: BusRegister *m_bus; // modify the constructor to initialise the new member start::start(QWidget *p = nullptr) : QWidget(p) , m_bus(nullptr) { ... } // and the slot void start::on_BusRegistration_clicked() { if (!m_bus) { m_bus = new BusRegister(this); } m_bus->show(); }
-
what about if I want the main window object ( w ) to be visible in BusRegister.cpp so I can change the main window by clicking a button in the subwindow ( basically the reverse of the previous situation )
int main(int argc, char *argv[]) { QApplication a(argc, argv); start w; w.show(); return a.exec(); }
in BusRegister.cpp i want to do something like this but w obviously can't be accessed in BusRegister, 'return' is the button name
void BusRegister::on_Return_clicked() { this->close(); w.hide(); }
-
@Uchi maybe u can use signal/slot .
class BusRegister { ... signals: void sgnClose(); }; class start { private: BusRegister *m_bus; }; // connect the signal/slot connect(m_bus, &BusRegister::sgnClose, this, &start::close); // when you clicked the button, emit the signal "sgnClose" void BusRegister::on_Return_clicked() { this->close(); emit sgnClose(); }
-
@Gaobo said in [c++] opening window B by clicking a button on window A:
connect(m_bus, &BusRegister::sgnClose, this, &start::close);
Where should i write this?
I assumed that i should place it herestart::start(QWidget* parent) : QMainWindow(parent) , m_bus(nullptr) { ui.setupUi(this); connect(m_bus, &BusRegister::sgnClose, this, &start::close); }
but it doesn't really close or hide the main window
-
@Uchi said in [c++] opening window B by clicking a button on window A:
doesn't really close or hide the main window
Yes, you put the[Correct class, but apparently not right place. See the Note below.]connect()
in the right place.What does "really" mean here? Either the main window closes or it does not, how does it not "really" close??
I know nothing about what this "bus" is, but do you ever receive this signal?
connect(m_bus, &BusRegister::sgnClose, this, [this]() { qDebug() << "sgnClose received"; close(); } );
Note: in this/your code,
m_bus
must have been set to aBusRegister
instance at the time theconnect()
is called. But you are calling it from a constructor withm_bus(nullptr)
and no parameter to set it to aBusRegister
. That won't work.... Either create and pass in aBusRegister
or delay the call to theconnect()
until you do so. -
@JonB
so basically i can't create the signal because the object is initialized as nullso I decided to declare the m_bus before setting up the connection and removing the previous declaration.
It works now, thanks.start::start(QWidget* parent) : QMainWindow(parent) , m_bus(nullptr) { m_bus = new BusRegister(this); ui.setupUi(this); connect(m_bus, &BusRegister::sgnShow, this, &start::show); //i changed it to close to show }
-
@Uchi
Correct! At the time theconnect()
statement is issued both the signal & slot objects must be set to the instances to be connected, that's whatconnect()
does. Changing either of the objects later to an instance has no effect on the earlierconnect()
.