基本Qt应用程序(QMainWindow)中未显示小部件

ukl*_*kll 3 user-interface qt qwidget qmainwindow

我是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
Run Code Online (Sandbox Code Playgroud)

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)));
}
Run Code Online (Sandbox Code Playgroud)

main.cpp中

#include <QApplication>
#include "Window.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    Window window;
    window.show();

    return app.exec();
}
Run Code Online (Sandbox Code Playgroud)

我在代码中找不到任何错误.

提前致谢.

Ako*_*rth 8

一个QMainWindow必须有一个中央物件,即使它只是一个占位符.另请注意,它有自己的布局用于添加工具栏,菜单栏等 - 所以您可能希望mainLayout为中央窗口小部件设置布局(在代码中).

有关详细信息,请查看QMainWindow类参考.

要使您的窗口小部件在主窗口中可见,您可以像这样修改构造函数:

Window.cpp

#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);
}
Run Code Online (Sandbox Code Playgroud)


Rei*_*ica 5

使用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);
};
Run Code Online (Sandbox Code Playgroud)

然后构造函数减少到:

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)));
}
Run Code Online (Sandbox Code Playgroud)

要尝试一下,您可能希望将其全部放在一个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"
Run Code Online (Sandbox Code Playgroud)

在尝试编译之前,请确保在项目上重新运行qmake.

对于给定的foo.cpp文件,#include "foo.moc"最后需要.cpp通过moc 运行文件.例如,您可能希望私有的QObject类存在于.cpp文件中并在该文件中使用.然后,您不必将此类的接口分隔为单独的头文件.这在Qt 4和pre-C++ 11中更为重要,当时你没有lambdas并且不得不将插槽放入专用类中.在Qt 5中,您可以将信号连接到就地编写的仿函数,因此只需编写一个或两个插槽就不需要本地帮助程序对象类.

这种方法在您进行实验时非常有用.在这种情况下,将<1000行代码分布在三个或更多文件中相当适得其反.简短的实验都是关于简洁性的.实现进入类声明a-la Java,main.cpp通过moc 运行单个文件并在末尾附加moc输出(via #include "main.moc").默认Qt Creator生成的模板适用于"大"应用程序,而不适用于实验.

为了获得灵感,我的stackoverflown答案库中大约有200个这样的大多数单文件示例:)每个示例的文件夹都在最后附加了SO问题编号,以便于查找上下文的SO问题.

如果你担心接口标题被实现细节污染,那么pimpl习惯用法就会出现问题:

// 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);
}
Run Code Online (Sandbox Code Playgroud)