Pregunta

I have two widgets (Real and Fake) and one of them has a QPushButton. Now I want the same button to be shown in the other widget. How do I do it?

I dont want to create a copy, I want the same QObject on to be shown another widget at the same time without changing the parent.

As an example, in the following I want "mybutton" to be shown in both the widgets at the same time;

  QWidget *widgetReal = new QWidget();
  QWidget *widgetFake = new QWidget();
  widgetReal->setWindowTitle("Real");
  widgetFake->setWindowTitle("Fake");
  widgetReal->show();
  widgetFake->show();

  QGridLayout *layoutReal = new QGridLayout();
  QGridLayout *layoutFake = new QGridLayout();

  QPushButton *mybutton = new QPushButton();

  layoutReal->addWidget(mybutton);
  widgetReal->setLayout(layoutReal);

  layoutFake->addWidget(mybutton); //this changes the parent and this is not what I want to do
  widgetFake->setLayout(layoutFake);

  mybutton->show();

The reason I need this is because I have a bunch of MDISubWindows and they contain some controls (buttons, checkboxes....etc). Now I want to select some of these controls from these widgets and create a single widget. The reason am doing this is because, I dont want to display all of my MDISubwindow when am using only single button in it Any suggestions are really helpful. Thank you.

-CV

¿Fue útil?

Solución 5

Anyways, I designed a hack to this. What I am trying to do is separate the appearance from the actual button object. Here's a sample code which needs to be extended for more functionality

file:: VirtualQPushButton.h

#ifndef VIRTUALQPUSHBUTTON_H
#define VIRTUALQPUSHBUTTON_H
#include <QPushButton>
//! \class Class that forwards signals to the base button
class VirtualQPushButton : public QPushButton
{
  Q_OBJECT
public:
  VirtualQPushButton (QPushButton &basebutton, QWidget * parent = 0) :
    QPushButton (parent),
    m_button (&basebutton)
  {
    QObject::connect(this, SIGNAL(clicked()), this, SLOT(forwardClick()));
    //don't forget to forward other signals too
  }

protected slots:
  void forwardClick()
  {
    if (m_button)
    {
      m_button->click();
    }
  }

private:
  QPushButton *m_button;
};
#endif // VIRTUALQPUSHBUTTON_H

file:: main.cpp

#include <QtGui/QApplication>
#include <QHBoxLayout>
#include "VirtualQPushButton.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget w;

    QPushButton *basebutton = new QPushButton (&w);
    basebutton->hide();
    QObject::connect (basebutton, SIGNAL (clicked()), &w, SLOT (close()));

    VirtualQPushButton *buton1 = new VirtualQPushButton (*basebutton);
    buton1->setText("Buton1");
    VirtualQPushButton *buton2 = new VirtualQPushButton (*basebutton);
    buton2->setText("Buton2");

    QHBoxLayout *lyt = new QHBoxLayout();
    lyt->addWidget(buton1);
    lyt->addWidget(buton2);
    w.setLayout(lyt);
    w.show();

    return a.exec();
}

Let me know what you opinions, thanks for all your responses.

CV

Otros consejos

QWidgets are to supposed to have only a single parent. No doubt you could come up with some hack that would let you achieve roughly what you want, but why do that when you could re-design to fit in with the way the Qt GUI system works?

Don't try and fight against the framework. If you do you'll just end up with hard-to-understand and hard-to-maintain code.

Qt doesn't support what you want to do so I'll quote stu's response:

Don't try and fight against the framework. If you do you'll just end up with hard-to-understand and hard-to-maintain code.

Although a widget can't be in multiple places at once, you can make it appear to be so:

void MyWidget::paintEvent(QPaintEvent *e) {
    QPainter p(this);
    QWidget *w = getRepeatableWidget();
    w->render(this, getPosition1());
    w->render(this, getPosition2());
}

Once you've done that, you would need to handle any clicks and other events and make it appear they were forwarded, etc., but you'll lose the focus hints and other things unless you put forth a lot of effort.

Don't think you can; a widget has only one parent at a time. You could move it around with setParent() but not have it show simultaneously in several parents.

Rather than trying to share a button between multiples parents, you can create QActions and embed them in multiple QToolButton (with QToolButton::setDefaultAction) or by adding the action to a QToolBar.

QAction can be checkable/togglable, and can be added to exclusive groups (QActionGroup) to have the same behavior as radio buttons. All QToolButtons properties and states will be kept in sync with the ones from the QAction they are linked to.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top