请使用
QWidget
代替
QMainWindow
。后者不适合与您正在执行的布局直接使用。除非您明确需要其提供的功能(工具栏、停靠区等),否则不要使用
QMainWindow
。如果您真的想使用
QMainWindow
,那么
Akos 的优秀答案展示了如何做到这一点。
任何小部件,甚至是简单的
QLabel
都可以成为您的“主”小部件。
您也不需要动态分配小部件的所有复杂性。
只需执行以下操作:
class Window : public QWidget
{
Q_OBJECT
QGridLayout m_layout;
QLabel m_label;
QLineEdit m_lineEdit;
public:
explicit Window(QWidget *parent = 0);
};
然后构造函数就减少为:
Window::Window(QWidget *parent)
: QWidget(parent), m_layout(this), m_label(tr("Text"))
{
m_layout.addWidget(&m_label, 0, 0);
m_layout.addWidget(&m_lineEdit, 1, 0);
connect(&m_lineEdit, SIGNAL(textChanged(QString)),
&m_label, SLOT(setText(QString)));
}
为了尝试这些内容,您可能希望将它们全部放在一个名为 main.cpp
的文件中:
#include <QApplication>
#include <QLabel>
#include <QTextEdit>
class Window : public QWidget
{
Q_OBJECT
QGridLayout m_layout;
QLabel m_label;
QLineEdit m_lineEdit;
public:
explicit Window(QWidget *parent = 0) : QWidget(parent),
m_layout(this), m_label(tr("Text"))
{
m_layout.addWidget(&m_label, 0, 0);
m_layout.addWidget(&m_lineEdit, 1, 0);
connect(&m_lineEdit, SIGNAL(textChanged(QString)),
&m_label, SLOT(setText(QString)));
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Window window;
window.show();
return app.exec();
}
#include "main.moc"
在尝试编译项目之前,请确保重新运行项目中的qmake。
对于给定的foo.cpp
文件,当您想通过moc运行.cpp
文件时,需要在末尾包含#include "foo.moc"
。例如,您可能希望使用一个私有的基于QObject
的类,该类存在于.cpp
文件中并在该文件中使用。您不必将此类的接口分离到单独的头文件中。这在Qt 4和C++11之前更为重要,因为您没有lambda并且必须将slot放入专用类中。在Qt 5中,您可以将信号连接到原地编写的函数对象,因此几乎不需要本地辅助对象类来编写一个或两个slot。
这种方法在进行实验时非常有用。将小于1000行的代码分散到三个或更多文件中,在这种情况下相当低效。短期实验需要简洁明了。实现采用Java风格的类声明,通过moc运行单个main.cpp文件,并在末尾附加moc输出(通过#include "main.moc")。默认的Qt Creator生成的模板适用于“大型”应用程序,而不适用于实验。
如果需要灵感,我的
stackoverflown答案仓库中有大约200个这样的主要是单个文件的示例:)每个示例的文件夹末尾都附有SO问题号,以便轻松查找上下文相关的SO问题。
如果您担心接口头文件被实现细节污染,那么
pimpl习惯用法就来拯救了:
#ifndef MY_WINDOW_H
#define MY_WINDOW_H
#include <QWidget>
#include <QScopedPointer>
class WindowPrivate;
class Window : public QWidget {
Q_OBJECT
Q_DECLARE_PRIVATE(Window)
QScopedPointer<WindowPrivate> const d_ptr;
public:
explicit Window(QWidget *parent = 0);
~Window();
QString text() const;
};
#endif
#include "window.h"
#include <QLabel>
#include <QLineEdit>
#include <QGridLayout>
class WindowPrivate {
Q_DISABLE_COPY
public:
explicit WindowPrivate(Window *);
QGridLayout layout;
QLabel label;
QLineEdit lineEdit;
};
Window::Window(QWidget * parent) : QWidget(parent), d_ptr(new WindowPrivate(this))
{
Q_D(Window);
connect(&d->lineEdit, SIGNAL(textChanged(QString)),
&d->label, SLOT(setText(QString)));
}
Window::~Window() {}
QString Window::text() const {
Q_D(const Window);
return d->label.text();
}
WindowPrivate::WindowPrivate(Window * window) :
layout(window), label(tr("Text"))
{
layout.addWidget(label, 0, 0);
layout.addWidget(lineEdit, 1, 0);
}