我是Qt的新手,我正在用简单的例子做一些练习。
我只是想用一个简单的应用程序来测试我的知识,通过编码,用户在QLineEdit小部件中键入文本,文本将显示在QLabel中。没有必要使它有用。我只是想试试。
在编译应用程序时,我没有错误。但是,打开窗口时,QLabel和QLineEdit小部件不可见。
我的代码在这里:
window.h中
#ifndef WINDOW_H
#define WINDOW_H
#include <QMainWindow>
class QGridLayout;
class QLabel;
class QLineEdit;
class Window : public QMainWindow
{
Q_OBJECT
public:
explicit Window(QWidget *parent = 0);
private:
QGridLayout *mainLayout;
QLabel *label;
QLineEdit *lineEdit;
};
#endif // WINDOW_H
Window.cpp
#include "Window.h"
#include <QGridLayout>
#include <QLineEdit>
#include <QLabel>
Window::Window(QWidget *parent)
: QMainWindow(parent)
{
mainLayout = new QGridLayout;
label = new QLabel(tr("Text"));
lineEdit = new QLineEdit;
mainLayout->addWidget(label, 0, 0);
mainLayout->addWidget(lineEdit, 1, 0);
setLayout(mainLayout);
connect(lineEdit, SIGNAL(textChanged(QString)),
label, SLOT(setText(QString)));
}
的main.cpp
#include <QApplication>
#include "Window.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Window window;
window.show();
return app.exec();
}
我在代码中找不到任何错误。
提前谢谢。
答案 0 :(得分:8)
QMainWindow
必须有一个中央窗口小部件,即使它只是一个占位符。另请注意,它有自己的布局用于添加工具栏,菜单栏等 - 所以您可能希望为中央窗口小部件设置布局(mainLayout
)。
查看QMainWindow class reference了解详情。
要使您的窗口小部件在主窗口中可见,您可以像这样修改构造函数:
#include "Window.h"
#include <QGridLayout>
#include <QLineEdit>
#include <QLabel>
Window::Window(QWidget *parent)
: QMainWindow(parent)
{
QWidget* someWidget = new QWidget(this);
mainLayout = new QGridLayout;
label = new QLabel(tr("Text"));
lineEdit = new QLineEdit;
mainLayout->addWidget(label, 0, 0);
mainLayout->addWidget(lineEdit, 1, 0);
someWidget->setLayout(mainLayout);
connect(lineEdit, SIGNAL(textChanged(QString)),
label, SLOT(setText(QString)));
setCentralWidget(someWidget);
}
答案 1 :(得分:5)
使用QWidget
代替QMainWindow
。后者并不意味着直接使用像你一样的布局。除非您明确需要它提供的功能(工具栏,停靠区域等),否则不要使用QMainWindow
。如果您确实想使用QMainWindow
,那么Akos's excellent answer会显示如何执行此操作。
任何小部件,即使是简单的QLabel
也可以是您的&#34; main&#34;窗口小部件。
您也不需要动态分配小部件的所有复杂功能。
简单地说:
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运行#include "foo.moc"
文件时,最后需要.cpp
。例如,您可能希望私有QObject
派生类存在于.cpp
文件中并在该文件中使用。然后,您不必将此类的接口分成单独的头文件。这在Qt 4和pre-C ++ 11中更为重要,当时你没有lambdas并且不得不将插槽放入专用类中。在Qt 5中,您可以将信号连接到就地编写的仿函数,因此只需编写一两个插槽就不需要本地帮助程序对象类。
这种方法在您进行实验时非常有用。在这种情况下,将&lt; 1000行代码扩展到三个或更多文件是相当适得其反的。简短的实验都是关于简洁性的。实现进入类声明a-la Java,通过moc运行单个main.cpp
文件并在末尾附加moc输出(通过#include "main.moc"
)。默认Qt Creator生成的模板适用于&#34; big&#34;应用,而非实验。
为了获得灵感,我的stackoverflown answer repository上大约有200个这样的大多数单个文件示例:)每个示例的文件夹都在最后附加了SO问题编号,以便于查找上下文的SO问题。
如果您担心接口标头被实施细节污染,pimpl idiom就会出现问题:
// window.h
#ifndef MY_WINDOW_H
#define MY_WINDOW_H
#include <QWidget>
#include <QScopedPointer>
// This only provides a public interface.
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
// window.cpp
#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);
// This code really belongs in WindowPrivate constructor.
// It is shown here to illustrate how the non-const pimpl is accessed.
connect(&d->lineEdit, SIGNAL(textChanged(QString)),
&d->label, SLOT(setText(QString)));
}
// Needed here since the ~WindowPrivate is not visible outside of this file.
Window::~Window() {}
QString Window::text() const {
Q_D(const Window);
// This is how you access const pimpl
return d->label.text();
}
WindowPrivate::WindowPrivate(Window * window) :
layout(window), label(tr("Text"))
{
layout.addWidget(label, 0, 0);
layout.addWidget(lineEdit, 1, 0);
}