Qt 应用程序 C++ 的自定义小部件
Custom widget for Qt Application C++
我有 2 个 .ui 使用 Qt Designer 创建的文件
main_window.ui
- class QMainWindow(名称 MyWindow)仅包含 1 个 QTabWidget
my_widget.ui
- class QWidget(名称 MyWidget)每个包含一个 QLabel 和 QPushButton
我有一个配置文件,内容如下
ProcessA Tab1 ; ProcessB Tab2 ; ProcessC Tab1
从上面很清楚,我需要A和C在Tab1中,B在Tab2中。我已经能够创建所需的选项卡。我想创建第二个 UI 的实例并填充选项卡。
我已经能够使用 QPushButton class 而不是 MyWidget Class 并得到以下输出(正确)
当我尝试使用 MyWidget Class 时,我最终得到的是空白标签。
代码概述 -
MyWindow::setupTabs(std::string fileName)
{
Read file
for each process in file:
MyWidget *temp = new MyWidget();
Fill text in label and button
Create std::vector<std::vector<MyWidget*> > and fill according to tabs
for each tab call populateTab()
}
MyWindow::populateTab(processList, tabName)
{
QFrame* group = new QFrame();
QVBoxLayout* vbox = new QVBoxLayout();
vbox->setSpacing(0);
group->setLayout(vbox);
QScrollArea* scrollArea = new QScrollArea();
for (size_t i = 0; i < processList.size(); ++i)
vbox->addWidget(processList[i]); //vbox->addWidget(new QPushButton); works fine
scrollArea->setWidget(group);
ui->tabWidget->addTab(scrollArea, tabName);
}
setupTabs 函数完全按照预期执行,因此我已经非常简要地提到了代码。
MyWidget.h 看起来像这样
namespace Ui {
class MyWidget;
}
class MyWidget : public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent = 0);
~MyWidget();
private:
Ui::MyWidget *ui;
};
请让我知道我做错了什么。
从你的伪代码中有点难以分辨,但你似乎总是在布局中添加相同的小部件 (MyWidget)。您的最后一个选项卡是否包含小部件,而其他选项卡不包含?
此致
最小示例:
mainwindow.hpp
#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_HPP
mainwindow.cpp(仅包含一个名为 tabWidget 的 QTabWidget 的 QMainWindow)
#include "mainwindow.hpp"
#include "ui_mainwindow.h"
#include "form.hpp"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->tabWidget->clear(); // Clear the two Tabs that are shown by default
QStringList fileEntries(QStringList() << "widget1" << "widget2" << "widget3" << "widget4"); // A QStringList simulating the file entries
int count = 1;
foreach (QString entry, fileEntries) { // Loop through all the entries and add the custom widget on the go
Form *myWidget = new Form(this);
myWidget->set(entry + "Label", entry + "Button");
ui->tabWidget->addTab(myWidget, "New Tab " + QString::number(count++));
}
}
MainWindow::~MainWindow()
{
delete ui;
}
form.hpp(应代表您的 MyWidget)。它在 QVBoxLayout 中包含一个 QLabel 和一个 QPushButton:
#ifndef FORM_HPP
#define FORM_HPP
#include <QWidget>
namespace Ui {
class Form;
}
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = 0);
~Form();
void set(QString const&labelText, QString const&buttonText);
private:
Ui::Form *ui;
};
#endif // FORM_HPP
form.cpp:
#include "form.hpp"
#include "ui_form.h"
Form::Form(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form)
{
ui->setupUi(this);
}
Form::~Form()
{
delete ui;
}
void Form::set(const QString &labelText, const QString &buttonText)
{
ui->label->setText(labelText);
ui->pushButton->setText(buttonText);
}
form.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
希望对您有所帮助,
此致
第二次编辑,与上面的示例相同,但是 form.ui 在表单 (QWidget) 上不再有布局(至少看起来像您描述中的问题):
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>737</width>
<height>523</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>480</x>
<y>350</y>
<width>160</width>
<height>80</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>
此致
我有 2 个 .ui 使用 Qt Designer 创建的文件
main_window.ui
- class QMainWindow(名称 MyWindow)仅包含 1 个 QTabWidgetmy_widget.ui
- class QWidget(名称 MyWidget)每个包含一个 QLabel 和 QPushButton
我有一个配置文件,内容如下
ProcessA Tab1 ; ProcessB Tab2 ; ProcessC Tab1
从上面很清楚,我需要A和C在Tab1中,B在Tab2中。我已经能够创建所需的选项卡。我想创建第二个 UI 的实例并填充选项卡。
我已经能够使用 QPushButton class 而不是 MyWidget Class 并得到以下输出(正确)
当我尝试使用 MyWidget Class 时,我最终得到的是空白标签。
代码概述 -
MyWindow::setupTabs(std::string fileName)
{
Read file
for each process in file:
MyWidget *temp = new MyWidget();
Fill text in label and button
Create std::vector<std::vector<MyWidget*> > and fill according to tabs
for each tab call populateTab()
}
MyWindow::populateTab(processList, tabName)
{
QFrame* group = new QFrame();
QVBoxLayout* vbox = new QVBoxLayout();
vbox->setSpacing(0);
group->setLayout(vbox);
QScrollArea* scrollArea = new QScrollArea();
for (size_t i = 0; i < processList.size(); ++i)
vbox->addWidget(processList[i]); //vbox->addWidget(new QPushButton); works fine
scrollArea->setWidget(group);
ui->tabWidget->addTab(scrollArea, tabName);
}
setupTabs 函数完全按照预期执行,因此我已经非常简要地提到了代码。
MyWidget.h 看起来像这样
namespace Ui {
class MyWidget;
}
class MyWidget : public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent = 0);
~MyWidget();
private:
Ui::MyWidget *ui;
};
请让我知道我做错了什么。
从你的伪代码中有点难以分辨,但你似乎总是在布局中添加相同的小部件 (MyWidget)。您的最后一个选项卡是否包含小部件,而其他选项卡不包含?
此致
最小示例:
mainwindow.hpp
#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_HPP
mainwindow.cpp(仅包含一个名为 tabWidget 的 QTabWidget 的 QMainWindow)
#include "mainwindow.hpp"
#include "ui_mainwindow.h"
#include "form.hpp"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->tabWidget->clear(); // Clear the two Tabs that are shown by default
QStringList fileEntries(QStringList() << "widget1" << "widget2" << "widget3" << "widget4"); // A QStringList simulating the file entries
int count = 1;
foreach (QString entry, fileEntries) { // Loop through all the entries and add the custom widget on the go
Form *myWidget = new Form(this);
myWidget->set(entry + "Label", entry + "Button");
ui->tabWidget->addTab(myWidget, "New Tab " + QString::number(count++));
}
}
MainWindow::~MainWindow()
{
delete ui;
}
form.hpp(应代表您的 MyWidget)。它在 QVBoxLayout 中包含一个 QLabel 和一个 QPushButton:
#ifndef FORM_HPP
#define FORM_HPP
#include <QWidget>
namespace Ui {
class Form;
}
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = 0);
~Form();
void set(QString const&labelText, QString const&buttonText);
private:
Ui::Form *ui;
};
#endif // FORM_HPP
form.cpp:
#include "form.hpp"
#include "ui_form.h"
Form::Form(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form)
{
ui->setupUi(this);
}
Form::~Form()
{
delete ui;
}
void Form::set(const QString &labelText, const QString &buttonText)
{
ui->label->setText(labelText);
ui->pushButton->setText(buttonText);
}
form.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
希望对您有所帮助,
此致
第二次编辑,与上面的示例相同,但是 form.ui 在表单 (QWidget) 上不再有布局(至少看起来像您描述中的问题):
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>737</width>
<height>523</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>480</x>
<y>350</y>
<width>160</width>
<height>80</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>
此致