I am trying to use keyPressEvent in a mainwindow I generated with QtDesigner but no key press is detected by my program. Here is my code
The QtDesigner generated class is MainWindowUI.
class MainWindow(QMainWindow,MainWindowUI.Ui_MainWindow):
def __init__(self, translator,parent=None):
QMainWindow.__init__(self, parent=parent)
#super(MainWindow,self).__init__(parent)
self.setupUi(self)
self.translator=translator
self.completeGUI()
def completeGUI(self):
self.setConnections()
self.set_line_edit_validators()
self.category_combo.insertSeparator(4)
self.category_combo.insertSeparator(8)
self.type_conjug_combo.insertSeparator(3)
self.type_conjug_combo.insertSeparator(6)
#self.type_conjug_combo.setItemData( 0, QtGui.QColor('red'), QtCore.Qt.ForegroundRole )
self.save_button.clicked.connect(self.fileSave)
self.category_label.hide()
self.category_combo.hide()
self.type_conjug_label.hide()
self.type_conjug_combo.hide()
self.grammar_combo.setStyleSheet("color:red")
self.category_combo.setStyleSheet("color:red;")
self.type_conjug_combo.setStyleSheet("color:red;")
self.palat_combo.setStyleSheet("color:red;")
self.accent_combo.setStyleSheet("color:red;")
self.terme_edit.setStyleSheet("border: 2px solid red;")
print("completeGUI is over")
def keyPressEvent(self, e):
print(e.key())
I had a look at various answers to analog question on this forum but I could not manage to have it working.
Thank you for help.
HERE IS A MINIMAL EXAMPLE THAT REPRODUCES THE TROUBLE
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication
import sys
from view.NewMainWindow import NewMainWindow
if __name__=='__main__':
app = QApplication(sys.argv)
translator = QtCore.QTranslator()
app.installTranslator(translator)
mainWindow = NewMainWindow(translator)
NewMainWindow.show(mainWindow)
#sys.exit(app.exec_())
current_exit_code=app.exec_()
app=None
AND THE NEWMAINWINDOW
from PyQt5.QtWidgets import QMainWindow
from gen import NewMainWindowUI
class NewMainWindow(QMainWindow,NewMainWindowUI.Ui_MainWindow):
def __init__(self,translator, parent=None):
super(NewMainWindow,self).__init__(parent)
self.setupUi(self)
print('init completed')
def keyPressEvent(self, e):
print('event detected')
print(e.key())
THE GENERATED INTERFACE
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'src/designer/newmainwindow.ui'
#
# Created by: PyQt5 UI code generator 5.13.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(130, 110, 113, 36))
self.lineEdit.setObjectName("lineEdit")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 29))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
I usually avoid calling a keyPressEvent from both the central widget and the main window, because, as #musicamante said, one could be "consuming" the other. Especially if you plan on switching between multiple central widgets.
You should instead create a slot on a QMainWindow object connected to the central widget's keyPressEvent (but name it something else, like onKeyPressEvent or something) and then you emit the event from inside the MainWindow's keyPressEvent, something like this:
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget
from PyQt5.QtCore import pyqtSignal, pyqtSlot
from PyQt5.QtGui import QKeyEvent
class MainWindow(QMainWindow):
key_pressed = pyqtSignal(QKeyEvent)
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
central_widget = NewWindow()
self.key_pressed.connect(central_widget.onKeyPressEvent)
self.setCentralWidget(central_widget)
...
def keyPressEvent(self, event: QKeyEvent) -> None:
self.key_pressed.emit(event)
return super().keyPressEvent(event)
class NewWindow(QWidget):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
...
#pyqtSlot(QKeyEvent)
def onKeyPressEvent(self, event: QKeyEvent) -> None:
print(event.key())
return
Related
I am trying to make canvas for PyQt5 GUI. For this, I've used TkInter's canvas property. So I created a new widget in Qt Designer for tkinter's canvas.
As you can see from the picture below, I created promoted class for QWidget to use Canvas.
Then I converted this GUI into python code.
When I try to run my GUI, I'm getting the error which is on the title.
That's normal code:
from sympy import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from tkinter.messagebox import *
import sympy
import sys
from tkinter import Canvas
from untitled import *
class canvastrying(QMainWindow):
def __init__(self) -> None:
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = canvastrying()
sys.exit(app.exec_())
That's my GUI's code:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(318, 325)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.widget = Canvas(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(10, 20, 291, 231))
self.widget.setStyleSheet("background-color: green;")
self.widget.setObjectName("widget")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 318, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
from tkinter import Canvas
Can we use TkInter's canvas property in PyQt5? If we can, what am I doing wrong?
This question already has an answer here:
Get text from qtextedit and assign it to a variable
(1 answer)
Closed 2 years ago.
I need get text from QTextEdit, but have such trouble: Traceback (most recent call last):
File "main.py", line 28, in otpravit_naz
textboxValue = self.textEdit.text()
AttributeError: 'MyWin' object has no attribute 'textEdit'
This is my code(main.py):
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from test import *
import socket
sock = socket.socket()
class MyWin(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.otpravit.clicked.connect(self.otpravit_naz)
def mbox(self, body, title='Error'):
dialog = QMessageBox(QMessageBox.Information, title, body)
dialog.exec_()
def otpravit_naz(self):
print("1")
textboxValue = self.textEdit.text()
print(textboxValue)
#sock.connect(('192.168.1.16', 9090))
sock.connect(("192.168.1.45", 9090))
sock.send(b'textboxValue')
sock.close()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
myapp = MyWin()
myapp.show()
sys.exit(app.exec_())
And ui form:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(517, 283)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(60, 20, 421, 201))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setSpacing(23)
self.verticalLayout.setObjectName("verticalLayout")
self.textEdit = QtWidgets.QTextEdit(self.verticalLayoutWidget)
self.textEdit.setObjectName("textEdit")
self.verticalLayout.addWidget(self.textEdit)
self.label = QtWidgets.QLabel(self.verticalLayoutWidget)
self.label.setLineWidth(0)
self.label.setMidLineWidth(0)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.list = QtWidgets.QComboBox(self.verticalLayoutWidget)
self.list.setObjectName("list")
self.list.addItem("")
self.list.addItem("")
self.list.addItem("")
self.verticalLayout.addWidget(self.list)
self.otpravit = QtWidgets.QPushButton(self.verticalLayoutWidget)
self.otpravit.setObjectName("otpravit")
self.verticalLayout.addWidget(self.otpravit)
self.verticalLayout.setStretch(0, 20)
self.verticalLayout.setStretch(1, 20)
self.verticalLayout.setStretch(2, 20)
self.verticalLayout.setStretch(3, 20)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 517, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "Предмет:"))
self.list.setItemText(0, _translate("MainWindow", "Русский"))
self.list.setItemText(1, _translate("MainWindow", "Литература"))
self.list.setItemText(2, _translate("MainWindow", "Английский"))
self.otpravit.setText(_translate("MainWindow", "Отправить"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
If it very stupid troble, pls don't kick me
You're "installing" the GUI on the self.ui object, so every widget that is on the ui is actually accessible as self.ui.someWidget.
Also, QTextEdit doesn't have a text() property, but toPlainText():
def otpravit_naz(self):
print("1")
textboxValue = self.ui.textEdit.toPlainText()
print(textboxValue)
I suggest you to never edit the files generated with pyuic, but always use them as imported modules; read more on using Designer; also, be careful to set the main layout on the central widget, not on its children, and add everything to that layout, otherwise the children widgets could be hidden whenever the window is resized.
I'm trying to create an application, that can execute an embedded Terminal command when ever the button is clicked. The actual problem occurs when i click the button and nothing happens.
I have two scripts one has a terminal widget and the other has the main GUI. Any Help, would be highly appreciated.
That's first Script
import sys
from PyQt5 import QtCore, QtWidgets
class EmbTerminal(QtWidgets.QWidget):
def __init__(self, parent=None):
super(EmbTerminal, self).__init__(parent)
self._process = []
self.start_process('urxvt',['-embed', str(int(self.winId())),"-e","tmux"])
def start_process(self,prog,options):
child = QtCore.QProcess(self)
self._process.append(child)
child.start(prog,options)
def run_command(self, command = "ls" ):
program = "tmux"
options = []
options.extend(["send-keys"])
options.extend([command])
options.extend(["Enter"])
self.start_process(program, options)
That's Second Script
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(745, 496)
self.tabWidget = QtWidgets.QTabWidget(Dialog)
self.tabWidget.setGeometry(QtCore.QRect(100, 190, 561, 261))
self.tabWidget.setObjectName("tabWidget")
self.tab = QtWidgets.QWidget()
self.tab.setObjectName("tab")
self.tabWidget.addTab(EmbTerminal(), "Terminal")
self.tab_2 = QtWidgets.QWidget()
self.tab_2.setObjectName("tab_2")
self.tabWidget.addTab(self.tab_2, "")
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(280, 70, 211, 71))
self.pushButton.setObjectName("pushButton")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
self.pushButton.clicked.connect(lambda: EmbTerminal.run_command(EmbTerminal(), "ls"))
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("Dialog", "Tab 1"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("Dialog", "Tab 2"))
self.pushButton.setText(_translate("Dialog", "ls"))
from terminal5 import EmbTerminal
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
You should consider the following:
You should not modify the code generated by Qt Designer (unless you understand its logic)
Do not implement the logic in the class generated by Qt Designer, it is advisable to create a new class that inherits from the appropriate widget and use the other class to fill it.
In your case the problem is that the EmbTerminal() object in lambda: EmbTerminal.run_command(EmbTerminal(), "ls") only exists while the lambda is running, but the lambda runs for a very short time causing the command not to be sent causing the error.
Considering the above, the solution is:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(745, 496)
self.tabWidget = QtWidgets.QTabWidget(Dialog)
self.tabWidget.setGeometry(QtCore.QRect(100, 190, 561, 261))
self.tabWidget.setObjectName("tabWidget")
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(280, 70, 211, 71))
self.pushButton.setObjectName("pushButton")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton.setText(_translate("Dialog", "ls"))
from terminal5 import EmbTerminal
class Dialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.terminal = EmbTerminal()
self.tabWidget.addTab(self.terminal, "Terminal")
self.pushButton.clicked.connect(self.on_clicked)
#QtCore.pyqtSlot()
def on_clicked(self):
self.terminal.run_command("ls")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Dialog()
w.show()
sys.exit(app.exec_())
On the other hand if you are only going to send commands then it is not necessary to store the QProcess, instead use QProcess: startDetached and make run_command a classmethod:
class EmbTerminal(QtWidgets.QWidget):
# ...
#staticmethod
def run_command(command = "ls" ):
program = "tmux"
options = []
options.extend(["send-keys"])
options.extend([command])
options.extend(["Enter"])
QtCore.QProcess.startDetached(program, options)
I have made a UI which includes a mainwindow and a button that opens a dialog window. I want to send the current text changed signal from a line edit in the dialog window to the Mainwindow class as a variable. An example of the code I am making is below:
from PyQt5 import QtCore, QtGui, QtWidgets
from selenium import webdriver
import time
import threading
from bs4 import BeautifulSoup as soup
import requests
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(388, 179)
self.lineEdit_2 = QtWidgets.QLineEdit(Dialog)
self.lineEdit_2.setGeometry(QtCore.QRect(100, 100, 271, 21))
font = QtGui.QFont()
font.setFamily("Yu Gothic")
self.lineEdit_2.setFont(font)
self.lineEdit_2.setStyleSheet("background-color: transparent;\n"
"color: rgb(255, 255, 255);")
self.lineEdit_2.setObjectName("lineEdit_2")
class Dialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, parent=None):
QtWidgets.QDialog.__init__(self, parent)
self.setupUi(self)
# self.pushButton.pressed.connect(self.textEdit.clear)
# self.pushButton.pressed.connect(self.sejd)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
self.keyworddict = {}
self.count = {}
MainWindow.setObjectName("MainWindow")
MainWindow.resize(803, 538)
MainWindow.setMinimumSize(QtCore.QSize(0, 0))
MainWindow.setMaximumSize(QtCore.QSize(10000, 10000))
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
self.pushButton = QtWidgets.QPushButton(self.centralWidget)
self.pushButton.setGeometry(QtCore.QRect(180, 210, 75, 23))
font = QtGui.QFont()
font.setFamily("Yu Gothic")
font.setBold(True)
font.setWeight(75)
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralWidget)
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
self.pushButton.pressed.connect(self.on_Button_clicked)
def on_Button_clicked(self):
dialog = QtWidgets.QDialog()
dialog.ui = Ui_Dialog()
dialog.ui.setupUi(dialog)
dialog.setWindowTitle("Login")
dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
dialog.exec_()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.setWindowTitle("ui")
w.show()
sys.exit(app.exec_())
All help appreciated. I would preferably like an example using the code above.
There are at least two simple ways to do this. You can either connect a signal when the dialog is created, or just retrieve the text after the dialog closes:
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
...
def dialogTextChanged(self, text):
print(text)
def on_Button_clicked(self):
dialog = QtWidgets.QDialog()
dialog.ui = Ui_Dialog()
dialog.ui.setupUi(dialog)
# connect signal to slot
dialog.ui.lineEdit_2.textChanged.connect(self.dialogTextChanged)
dialog.setWindowTitle("Login")
# this is not needed
# dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
dialog.exec_()
# or retrieve text after dialog closes
print(dialog.ui.lineEdit_2.text())
dialog.deleteLater()
If this is a login dialog, you should probably have an accept button which is connected to the dialog's accept() slot. Then you can check the exit status of the dialog like this:
if dialog.exec_() == QtWidgets.QDialog.Accepted:
text = dialog.ui.lineEdit_2.text()
# do sothing with text ...
dialog.deleteLater()
I created a GUI with the hepl of QtCreator-->QtDesigner. The file is called mainwindow.ui. With the help of pyuic5 I created mainwindow.py
pyuic5 mainwindow.ui > mainwindow.py
and this is how it looks like:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(400, 300)
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
self.frame = QtWidgets.QFrame(self.centralWidget)
self.frame.setGeometry(QtCore.QRect(30, 20, 341, 191))
self.frame.setFrameShape(QtWidgets.QFrame.Panel)
self.frame.setFrameShadow(QtWidgets.QFrame.Sunken)
self.frame.setObjectName("frame")
MainWindow.setCentralWidget(self.centralWidget)
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 400, 23))
self.menuBar.setObjectName("menuBar")
MainWindow.setMenuBar(self.menuBar)
self.mainToolBar = QtWidgets.QToolBar(MainWindow)
self.mainToolBar.setObjectName("mainToolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
self.statusBar = QtWidgets.QStatusBar(MainWindow)
self.statusBar.setObjectName("statusBar")
MainWindow.setStatusBar(self.statusBar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
and wanted to import that in my main script main.py:
#!/usr/bin/env python3
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from mainwindow import *
import sys
def main():
app = QApplication(sys.argv)
instance = Ui_MainWindow()
#instance.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
...but nothing happens when I run it. How should my main.py look like to use that gui module?
Ok, I figured it myself. To use a GUI file in Python, created in QtCreator called mainwindow.py, my main.py should look something like this:
#!/usr/bin/env python3
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from mainwindow import *
import sys
class Main(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.show()
def main():
app = QApplication(sys.argv)
instance = Main()
#instance.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
My class Main(QMainWindow) must have a parent QMainWindow and not QWidget because QWidget doesn't have setCentralWidget method which is needed in mainwindow.py.