c++ - 如何使用 Qt 在代码中访问提升的小部件的 UI 元素?

标签 c++ qt qt5 qt-designer

所以我创建了一个类DemoPromotedWidget,它继承自QWidget。

然后我在设计器中创建了一个 Widget,为该小部件添加了一个名为 DemoLabel 的标签,并将该小部件提升为 DemoPromotedWidget 类...然后我将它移到了我的工具箱中,它现在位于“Scratchpad”下。

通常,使用 Qt 的设计器,我可以在相应的类文件中访问 UI 文件中的任何元素。但是,在 DemoPromotedWidget 中我不能。

我是否可以在 DemoPromotedWidget 中访问 DemoLabel,以便我可以调用类似...

ui->DemoPromotedWidget->setText("Updated Text");

这是我的 UI Designer 的图片,其中已经添加了 DemoPromotedWidget。 https://i.imgur.com/QdT0eeG.png

DemoPromotedWidget.h

#ifndef DEMOPROMOTEDWIDGET_H
#define DEMOPROMOTEDWIDGET_H

#include <QWidget>

class DemoPromotedWidget : public QWidget
{
    Q_OBJECT
public:
    explicit DemoPromotedWidget(QWidget *parent = nullptr);

signals:

public slots:
};

#endif // DEMOPROMOTEDWIDGET_H

DemoPromotedWidget.cpp

#include "demopromotedwidget.h"

DemoPromotedWidget::DemoPromotedWidget(QWidget *parent) : QWidget(parent)
{
    // How do I access DemoPromotedWidget->DemoLabel->setText()?????????????????????
}

这是我的 mainwindow.ui...

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>711</width>
    <height>418</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <widget class="DemoPromotedWidget" name="DemoPromotedWidget" native="true">
    <property name="geometry">
     <rect>
      <x>160</x>
      <y>60</y>
      <width>381</width>
      <height>191</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">background-color: black;
text-align: center;</string>
    </property>
    <widget class="QLabel" name="DemoLabel">
     <property name="geometry">
      <rect>
       <x>0</x>
       <y>5</y>
       <width>381</width>
       <height>181</height>
      </rect>
     </property>
     <property name="styleSheet">
      <string notr="true">color: white;
text-align: center;</string>
     </property>
     <property name="text">
      <string>DemoLabel</string>
     </property>
     <property name="alignment">
      <set>Qt::AlignCenter</set>
     </property>
    </widget>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>711</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <customwidgets>
  <customwidget>
   <class>DemoPromotedWidget</class>
   <extends>QWidget</extends>
   <header>demopromotedwidget.h</header>
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

最佳答案

您不应该将类的名称与小部件的名称一起使用,因此首先要做的是更改其名称:

enter image description here

第一个选项:

另一方面,DemoPromotedWidget 中的 QLabel 并不意味着 DemoPromotedWidget 可以访问 QLabel 并且在构造函数中较少,因为在该方法中它尚未添加到主窗口,一个可能的解决方案是创建一个属性,您可以在其中为其分配 QLabel:

demopromotedwidget.h

#ifndef DEMOPROMOTEDWIDGET_H
#define DEMOPROMOTEDWIDGET_H

#include <QLabel>
#include <QWidget>

class DemoPromotedWidget : public QWidget
{
    Q_OBJECT
public:
    explicit DemoPromotedWidget(QWidget *parent = nullptr);
    QLabel *getLabel() const;
    void setLabel(QLabel *value);
private:
    QLabel *label;
};

#endif // DEMOPROMOTEDWIDGET_H

demopromotedwidget.cpp

#include "demopromotedwidget.h"

DemoPromotedWidget::DemoPromotedWidget(QWidget *parent) : QWidget(parent)
{

}

QLabel *DemoPromotedWidget::getLabel() const
{
    return label;
}

void DemoPromotedWidget::setLabel(QLabel *value)
{
    label = value;
    if(label)
        label->setText("some text");
}

主窗口.cpp

...
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->widget->setLabel(ui->DemoLabel);
}
...

第二个选项:

另一种更简单的方法,但只有在使用 Qt Designer 添加小部件 (QLabel) 时才能完成,在本例中使用方法 showEvent()findChild():

demopromotedwidget.h

#ifndef DEMOPROMOTEDWIDGET_H
#define DEMOPROMOTEDWIDGET_H

#include <QLabel>
#include <QWidget>

class DemoPromotedWidget : public QWidget
{
    Q_OBJECT
public:
    explicit DemoPromotedWidget(QWidget *parent = nullptr);
private:
    QLabel *label;
protected:
    void showEvent(QShowEvent *event);
};

#endif // DEMOPROMOTEDWIDGET_H

demopromotedwidget.cpp

#include "demopromotedwidget.h"

DemoPromotedWidget::DemoPromotedWidget(QWidget *parent) : QWidget(parent)
{
}

void DemoPromotedWidget::showEvent(QShowEvent *event)
{
    label = findChild<QLabel *>("DemoLabel");
    if(label)
        label->setText("some text");
    QWidget::showEvent(event);
}

更新:

一种新的方法是创建一个 QWidget 表单,该表单具有 .ui.h.cpp:

enter image description here

enter image description here

enter image description here

正如我所说,创建一个与初始代码不同的新类具有 .ui,然后在 Qt Designer 的帮助下打开它并添加标签

enter image description here

但它也是一个您可以像在第一种方法中那样提升的类。

enter image description here

完整的例子可以在下面的link中找到

关于c++ - 如何使用 Qt 在代码中访问提升的小部件的 UI 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50378537/

相关文章:

c++ - 将矩阵复制到 C++ 中指针指向的位置

c++ - 在 Qt5 的 QWidget 中添加新按钮

C++:是否可以将 extern "C"函数与普通函数区分开来?

用于类型和非类型模板的 c++ auto

javascript - 如何在 QML 文本上的特定单词上添加颜色

c++ - openGL 纹理映射 - 没有细节,为什么?

c++ - Qt C++ 控制台服务器,等待套接字连接并同时接受输入?

c++ - 为什么在没有显式调用 `exec()` 或 `show()` 的情况下显示 QProgressDialog ?

android - 如何使用 QML 在 iOS 和 Android 上 [以正确的方式] 显示网页内容

c++ - 我正在尝试运行这个程序,但它给出了错误 initwindow() not initialized