title: Why does the "Python stop working" for this PyQt5 invoice GUI application when i clicked submit button?
body: <p>It will be pleasure for me if you can help me to solve this issue. I am practicing coding of PyQt5 Gui Application. This is the simple GUI application which generate invoice. But whenever i click submit(create invoice) button it stopped. I can't figure out the problem. Please help me to solve the problem.</p>
  <p>Update: Can anyone fix the code with no error?
  The Error message is:</p>
  <pre><code>&gt;&gt;&gt; Exception &quot;unhandled AttributeError&quot;
  'InvoiceForm' object has no attribute 'setCentralWidget'
  </code></pre>
  <p>The code has given below:-</p>
  <pre><code>import sys
  
  from PyQt5.QtCore import pyqtSignal, QSize, QSizeF, QDate
  from PyQt5.QtGui import QTextDocument, QTextCursor
  from PyQt5.QtWidgets import QWidget, QFormLayout, QLineEdit, QPlainTextEdit, QSpinBox, QDateEdit, QTableWidget, \
      QHeaderView, QPushButton, QHBoxLayout, QTextEdit, QApplication, QMainWindow
  
  
  class InvoiceForm(QWidget):
      submitted = pyqtSignal(dict)
  
      def __init__(self):
          super().__init__()
          self.setLayout(QFormLayout())
          self.inputs = dict()
          self.inputs['Customer Name'] = QLineEdit()
          self.inputs['Customer Address'] = QPlainTextEdit()
          self.inputs['Invoice Date'] = QDateEdit(date=QDate.currentDate(), calendarPopup=True)
          self.inputs['Days until Due'] = QSpinBox()
          for label, widget in self.inputs.items():
              self.layout().addRow(label, widget)
  
          self.line_items = QTableWidget(rowCount=10, columnCount=3)
          self.line_items.setHorizontalHeaderLabels(['Job', 'Rate', 'Hours'])
          self.line_items.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
          self.layout().addRow(self.line_items)
          for row in range(self.line_items.rowCount()):
              for col in range(self.line_items.columnCount()):
                  if col &gt; 0:
                      w = QSpinBox()
                      self.line_items.setCellWidget(row, col, w)
  
          submit = QPushButton('Create Invoice', clicked=self.on_submit)
          self.layout().addRow(submit)
  
      def on_submit(self):
          data = {'c_name': self.inputs['Customer Name'].text(),
                  'c_addr': self.inputs['Customer Address'].toPlainText(),
                  'i_date': self.inputs['Invoice Date'].date().toString(),
                  'i_due': self.inputs['Invoice Date'].date().addDays(self.inputs['Days until Due'].value()).toString(),
                  'i_terms': '{} days'.format(self.inputs['Days until Due'].value()),
                  'line_items': list()}
  
          for row in range(self.line_items.rowCount()):
              if not self.line_items.item(row, 0):
                  continue
              job = self.line_items.item(row, 0).text()
              rate = self.line_items.cellWidget(row, 1).value()
              hours = self.line_items.cellWidget(row, 2).value()
              total = rate * hours
              row_data = [job, rate, hours, total]
              if any(row_data):
                  data['line_items'].append(row_data)
  
          data['total_due'] = sum(x[3] for x in data['line_items'])
  
          self.submitted.emit(data)
          main = QWidget()
          main.setLayout(QHBoxLayout())
          self.setCentralWidget(main)
  
          form = InvoiceForm()
          main.layout().addWidget(form)
          self.preview = InvoiceView()
          main.layout().addWidget(self.preview)
          form.submitted.connect(self.preview.build_invoice)
  
  class InvoiceView(QTextEdit):
      dpi = 72
      doc_width = 8.5 * dpi
      doc_height = 11 * dpi
  
      def __init__(self):
          super().__init__(readOnly=True)
          self.setFixedSize(QSize(self.doc_width, self.doc_height))
  
      def build_invoice(self, data):
          document = QTextDocument()
          self.setDocument(document)
          document.setPageSize(QSizeF(self.doc_width, self.doc_height))
          cursor = QTextCursor(document)
          cursor.insertText(&quot;Invoice, woohoo!&quot;)
  
  def main():
      app = QApplication(sys.argv)
      window = InvoiceForm()
      window.show()
      app.exec_()
  
  if __name__ == '__main__':
      main()
  </code></pre>