在多个小部件上显示相同的 QPushButton

Posted

技术标签:

【中文标题】在多个小部件上显示相同的 QPushButton【英文标题】:Showing the same QPushButton on multiple widgets 【发布时间】:2011-08-12 15:52:39 【问题描述】:

我有两个小部件(真实的和假的),其中一个有一个 QPushButton。现在我希望在另一个小部件中显示相同的按钮。我该怎么做?

我不想创建副本,我希望在不更改父级的情况下同时显示同一个 QObject 上的另一个小部件。

例如,在下面我希望“mybutton”同时显示在两个小部件中;

  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();

我需要这个的原因是因为我有一堆 MDISubWindows,它们包含一些控件(按钮、复选框......等)。现在我想从这些小部件中选择其中一些控件并创建一个小部件。这样做的原因是,当我只使用一个按钮时,我不想显示我的所有 MDISubwindow 任何建议都非常有帮助。谢谢。

-简历

【问题讨论】:

为什么需要这个?你想完成什么? 我编辑了回答您评论的问题 【参考方案1】:

QWidgets 应该只有一个父级。毫无疑问,您可以想出一些技巧来大致实现您想要的,但是当您可以重新设计以适应 Qt GUI 系统的工作方式时,为什么还要这样做呢?

不要试图与框架作斗争。如果你这样做了,你最终会得到难以理解和难以维护的代码。

【讨论】:

我明白这一点。但是如果我们从不同的角度来看按钮元素的设计,“按钮对象”是否应该与其外观分开,即一个按钮对象可以出现在很多地方。【参考方案2】:

Qt 不支持你想做的,所以我会引用stu's response:

不要试图与框架作斗争。如果你这样做了,你最终会得到难以理解和难以维护的代码。

虽然一个小部件不能同时出现在多个位置,但您可以让它看起来像这样:

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

完成此操作后,您将需要处理任何点击和其他事件,并使其显示为已转发等,但除非您付出很多努力,否则您将失去焦点提示和其他内容.

【讨论】:

【参考方案3】:

不要认为你可以;一个小部件一次只有一个父级。您可以使用 setParent() 移动它,但不能让它同时显示在多个父级中。

【讨论】:

我可能最终只是这样做,但即使在这种情况下,它也可能使我的代码变得混乱,因为有时我评估孩子并连接然后使用 SignalMapper。【参考方案4】:

您可以创建 QActions 并将它们嵌入到多个 QToolButton(使用 QToolButton::setDefaultAction)或通过将操作添加到 QToolBar 中,而不是尝试在多个父级之间共享一个按钮。

QAction 可以是可检查/可切换的,并且可以添加到独占组 (QActionGroup) 以具有与单选按钮相同的行为。 所有 QToolButtons 属性和状态都将与它们链接到的 QAction 中的属性和状态保持同步。

【讨论】:

好吧,现在这是一种变通方法,仅适用于某些特定情况。如果我想要一个完整的重复小部件(但不是副本),那么这是行不通的。我的意思是,我们可以破解它,但这会违反大部分规则并使代码更难理解:D【参考方案5】:

无论如何,我为此设计了一个技巧。我想要做的是将外观与实际按钮对象分开。这是一个示例代码,需要扩展以获得更多功能

文件:: 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

文件:: 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();

让我知道您的意见,感谢您的所有回复。

简历

【讨论】:

如果我想要两个由 Qt Designer 创建和提升的按钮,我该怎么做?如果我使用静态实例,我会收到错误,因为小部件期望应用程序之前运行。我没有机会在promote中使用构造函数。

以上是关于在多个小部件上显示相同的 QPushButton的主要内容,如果未能解决你的问题,请参考以下文章

如何同时在不同的 QT 小部件上显示多个视频

如何在多个小部件中使用相同的块

如何通过单击放置在同一页面上的小部件来显示不同的小部件

带有媒体上传按钮的自定义Wordpress窗口小部件,在每个窗口小部件上插入相同的图像

Android:多个 AppWidgets - 一个清单条目

动画列表多个小部件使用相同的 GlobalKey