PyQt - Correct Position Of Import Statements - python

In light of segregating/organising code, am lost on the best approach. The below works, with app.py imports after the MainWindow instantiation, but will that create subsequent problems, as I can't see how else things can be done (putting the imports after MainWindow is instantiated obviously gives 'main not found' from formatting.py).
app.py
from PyQt4.QtCore import *; from PyQt4.QtGui import *; from PyQt4.uic import *; from PyQt4.QtSql import *
app = QApplication(sys.argv)
class Main(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setMaximumSize(500,500); self.showMaximized()
def test(self):
print self.sender()
main = Main()
main.show()
from ui.formatting import *
formatting.py
from PyQt4.QtCore import *; from PyQt4.QtGui import *; from PyQt4.uic import *; from PyQt4.QtSql import *
from app import main
class LineEdit(QLineEdit):
def __init__(self):
QLineEdit.__init__(self)
self.setParent(main)
self.show()
self.textChanged.connect(main.test)
lineEdit = LineEdit()
Much appreciated

You should never rely on an object being instantiated when the import takes place (OK, there are a few times when you might want to do this, but it's very rare).
Instead, generally, you should use import statements to import modules, classes and/or functions. If an imported module/class/function requires access to something from another import (or from your main script) then you should pass that in explicitly when you use/instantiate/call said module/class/function.
So your example becomes:
formatting.py
from PyQt4.QtCore import *; from PyQt4.QtGui import *; from PyQt4.uic import *; from PyQt4.QtSql import *
class LineEdit(QLineEdit):
def __init__(self, main):
QLineEdit.__init__(self)
self.setParent(main)
self.show()
self.textChanged.connect(main.test)
app.py
from PyQt4.QtCore import *; from PyQt4.QtGui import *; from PyQt4.uic import *; from PyQt4.QtSql import *
from ui.formatting import *
class Main(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setMaximumSize(500,500); self.showMaximized()
def test(self):
print self.sender()
app = QApplication(sys.argv)
main = Main()
lineedit = LineEdit(main)
main.show()
Of course, this is a bit of a contrived example because it makes more sense to set the parent, and make the connection with your QLineEdit in app.py. Eg:
lineedit = LineEdit()
lineedit.setParent(main)
lineedit.textChanged.connect(main.test)
And then in that case, you don't need to subclass QLineEdit at all.

Related

How to call an event from another class in PyQt5

I'm trying to call a mouse click event in QWebview to get a text by copy in the QWebView page but I don't know how. I have been trying to solve this for sometimes now.
Here is the minor code
import sys
from PyQt5.QtWidgets import *
from PyQt5 import Qt
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWebKitWidgets import *
class sw(QWebView):
def keyPressEvent(self, e):
clipboard=QApplication.clipboard()
data=clipboard.mimeData()
print(data.text)
super(Mainw, self).keyPressEvent(e)
class Mainw(QWidget):
def __init__(self):
super().__init__()
#QTextEdit().__init__()
self.m=QMenuBar(self)
self.file=self.m.addMenu("file")
self.new=QAction("new", self)
self.file.addAction(self.new)
ed=QWebView(self)
ed.setHtml(imported_data)
ed.setGeometry(20,30,400,400)
if __name__=="__main__":
a=QApplication(sys.argv)
app=Mainw()
#sb=app.open()
app.show()
sys.exit(a.exec_())
I know there are alot or errors in this code

how to use a promoted class in PyQt5?

in principal I reopen my question some days ago:
where-do-i-write-the-class-for-a-single-promoted-qwidget-from-qt-designer
The solution works, but I run into 2 more questions
if I want to change the text in the class neuLabel, how do i adress the class out of main program?
Additional information for minimal example as required:
I have a qt designer main window, named testpromote.ui. It contains only one label. Text is "MyLabel", the name is neuLabel and it is promoted as neulabel.
I need 2 .py files in one directory.
First the main testpromote.py
import sys
import os
from PyQt5 import uic
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import * #QPainter
import neulabel
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
uifile_1 = os.path.join(CURRENT_DIR, "testpromote.ui")
form_1, base_1 = uic.loadUiType(uifile_1)
class myApp(base_1, form_1):
def __init__(self):
super(base_1,self).__init__()
self.setupUi(self)
# ??????????????
#neuLabel.setText(neuLabel,"from main")
# ??????????????
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = myApp() #Dialog()
ex.show()
sys.exit(app.exec_())
2nd file is neulabel.py
from PyQt5.QtWidgets import *
from PyQt5 import uic
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import * #QPainter
class neuLabel(QLabel):
def __init__(self,parent=None):
super().__init__(parent)
self.setAcceptDrops(True)
self.setText("from code")
print("the new pixmap?", self.text())
My aim is to change the text of the label out of the main program testpromote.py
I do not understand, how to import the neulabel.py, so that i could change the text of the label.I tried it with "neuLabel.setText(neuLabel,"from main")", but this doesn't work. I tried it with other code too, but not succesfully. (This is marked within the # ????????? lines)
To see, if the text in the label changes, I added in neulabel.py the
self.setText() statement, but the text does not change in the window.
(i hope, it is clearer now)

In Pyqt5, QWindow, showMaximized() doesn't work. Why?

It's a tiny simple code.
In this code, self.showMaximized() is not working.
And even it's so tiny, I don't know why.
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Window(QWindow):
def __init__(self):
QWindow.__init__(self)
self.setTitle("title")
self.showMaximized()
# self.resize(400,300)
# self.showMaximized()
# self.showFullScreen()
app = QApplication(sys.argv)
screen = Window()
screen.show()
sys.exit(app.exec_())
Delete 'screen.show()', and then showMaximized() worked.
Either you need to use .showMaximized() only on newly created Object i.e., screen, but not in your constructor or only at the end of your constructor, but not twice.
Code:
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Window(QWindow):
def __init__(self):
QWindow.__init__(self)
self.setTitle("title")
app = QApplication(sys.argv)
screen = Window()
screen.showMaximized()
sys.exit(app.exec_())

PyQt5 signal communication error

I need your help with the following problem that I've encountered.
I have two Python files, Main.py and Module.py, which need to communicate using PyQt5 signals. Here's the code:
Main.py
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from MyGUI import main_window_GUI
from Modules import Module.py
class MainWindow(QMainWindow, main_window_GUI.Ui_main_window):
def __init__(self):
QMainWindow.__init__(self)
main_window_GUI.Ui_main_window.__init__(self)
self.setupUI(self)
sub_win = QMdiSubWindow()
sub_win.setWidget(Module.moduleWindow())
self.mdi.addSubWindow(sub_win)
# this part reports error saying:
# 'PyQt5.QtCore.pyqtSignal' object has no attribute 'connect'
Module.moduleWindow.my_signal.connect(self.do_something)
def do_something(self):
pass
Module.py
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from MyGUI import module_window_GUI
class moduleWindow(QMainWindow, module_window_GUI.Ui_module_window):
my_signal = pyqtSignal()
def __init__(self):
QMainWindow.__init__(self)
module_window_GUI.Ui_module_window.__init__(self)
self.setupUI(self)
# the rest is not important
# what is important is th following function
def closeEvent(self, event):
# when the user closes this subwindow signal needs to
# be emitted so that the MainWindow class knows that
# it's been closed.
self.my_signal.emit()
event.accept()
Any kind of help is more than welcome. Thanks in advance.
You need to connect the signal from an instance of the moduleWindow class, and not from the class itself:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from MyGUI import main_window_GUI
from Modules import Module
class MainWindow(QMainWindow, main_window_GUI.Ui_main_window):
def __init__(self):
QMainWindow.__init__(self)
main_window_GUI.Ui_main_window.__init__(self)
self.setupUI(self)
sub_win = QMdiSubWindow()
module_window = Module.moduleWindow()
sub_win.setWidget(module_window)
self.mdi.addSubWindow(sub_win)
module_window.my_signal.connect(self.do_something)
#pyqtSlot()
def do_something(self):
pass
I would also recommend to decorate the do_something method with pyqtSlot as reported in the documentation

PyQT5 with dbus interface freezes on interspection (where PyQT4 works)

I have a following simple snippet which works on PyQT4:
from PyQt4.QtCore import QCoreApplication
import math
import dbus
import dbus.service
from dbus.mainloop.qt import DBusQtMainLoop
class Calculator(dbus.service.Object):
def __init__(self):
busName = dbus.service.BusName('org.calc.Calculator', bus = dbus.SessionBus())
dbus.service.Object.__init__(self, busName, '/Calculator')
#dbus.service.method('org.calc.Calculator', in_signature = 'dd', out_signature = 'd')
def add(self, a, b):
return a+b
DBusQtMainLoop(set_as_default = True)
app = QCoreApplication([])
calc = Calculator()
app.exec_()
however, if I substitute the PyQT4 import for a PyQT5 one:
from PyQt5.QtCore import QCoreApplication
the application hangs on interspection.
Any ideas how to fix this? More imporantantly, what may be the cause?
Turns out with PyQt5 you need to use PyQt5 specific dbus module providing the mainloop:
from dbus.mainloop.pyqt5 import DBusQtMainLoop
instead of:
from dbus.mainloop.qt import DBusQtMainLoop

Categories