I'm trying to make a custom widget getting more and more descriptive with each sub class. For instance below, I'm adding to a list of boxes as I make them. I want do_stuff() to only run once but I want it to run on initialization. My problem is that I need all of the __setupUi() functions to run before I finish it. Any help is appreciated.
from PyQt5 import QtCore, QtWidgets
class layer4:
def __init__(self):
self.boxes = []
self.__setupUi()
# I want to run this once AFTER all of the children (regardless of how deep it goes) have run
self.do_stuff()
def __setupUi(self):
self.qsb = QtWidgets.QSpinBox()
self.boxes.append(self.qsb)
def do_stuff(self):
print(self.boxes)
class layer3(layer4):
def __init__(self):
super().__init__()
self.__setupUi()
def __setupUi(self):
self.qsb2 = QtWidgets.QSpinBox()
self.boxes.append(self.qsb2)
class layer2(layer3):
def __init__(self):
super().__init__()
self.__setupUi()
def __setupUi(self):
self.datetimebox = QtWidgets.QDateTimeEdit()
self.boxes.append(self.datetimebox)
class layer1(layer2):
def __init__(self):
super().__init__()
self.__setupUi()
def __setupUi(self):
self.other = QtWidgets.QDateTimeEdit()
self.boxes.append(self.other)
So if I run
t = layer2()
It should return 2 QSpinboxes and 1 datetimeedit
Related
This is the current code I am using:
class Opening(QDialog):
def __init__(self):
super(Opening, self).__init__()
loadUi("reminder2.ui", self)
self.startbutton.clicked.connect(self.gotomain)
def gotomain(self):
main = MainWindow()
widget.addWidget(main)
widget.setCurrentIndex(widget.currentIndex()+1)
class MainWindow(QDialog):
def __init__(self):
super(MainWindow, self).__init__()
loadUi("reminder.ui",self)
self.typebutton.clicked.connect(self.med)
self.searchbutton.clicked.connect(self.medd)
self.med2.hide()
self.med3.hide()
self.med4.hide()
self.med5.hide()
self.med6.hide()
self.med7.hide()
self.med8.hide()
self.addbutton.clicked.connect(self.clickAdd)
def med(self):
self.stackedWidget.setCurrentWidget(self.typemed)
def medd(self):
self.stackedWidget.setCurrentWidget(self.searchmed)
def clickAdd(self):
self.med2.show()
I have a main window created with PyQt5, i.e.:
class PrincipalClass(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_PrincipalForm()
self.ui.setupUi(self)
self.list = []
self.filename = ""
self.chars = ""
self.filename_noext = ""
I have also a function inside the class:
def checkchars(self):
self.chars = ""
if self.ui.minuscoleCb.isChecked():
self.chars += self.minuscole
if self.ui.maiuscoleCb.isChecked():
self.chars += self.maiuscole
if self.ui.numeriCb.isChecked():
self.chars += self.numeri
Now I want to create a QThread class with his run function that I want to use in order to do some calculations, but I need to use inside the QThread class the result of self.chars coming from the main window.
class External(QThread):
word = pyqtSignal(str)
def run(self):
How can I have the value of self.chars available inside the QThread class? I know that from QThread to main window I can use the signal way, but viceversa?
I succeeded in creating a gui crawling program using Beautiful Soup and PyQt5.
By the way, I had a problem with gui freeze while the program executed the repeating statement.
So I'm going to use QThread.
But when I bring the elements related to gui on Thread, there is a problem.
(There's no problem with operating code that has nothing to do with gui, so I don't think there's any data transmission between classes.) (Is this right?)
I've created a simple problem. ↓
import sys
import time
from PyQt5 import uic
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
form_class = uic.loadUiType('aaaa.ui')[0]
class Thread1(QThread):
def __init__(self, Main):
super().__init__(Main)
def run(self):
i = 1
while i <= 10:
print(self.lineEdit.text().strip()) #No data transmission between Main and Thread1??
time.sleep(1)
i += 1
class Main(QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setupUi(self)
self.initSetting()
self.initSignal()
def initSetting(self):
self.statusBar().showMessage('Wait')
self.setWindowTitle('aaaa')
def initSignal(self):
self.pushButton.clicked.connect(self.printWord)
def printWord(self):
self.statusBar().showMessage('Threading')
x = Thread1(self)
x.start()
if __name__ == "__main__" :
app = QApplication(sys.argv)
aaaa = Main()
aaaa.show()
app.exec_()
Using QThread, from what I understand, transmission of information between classes is doable, but to transmit information from your Main class to your Thread1 class, you have to pass arguments upon instantiation of your Thread1 class from your Main class.
In other words, your Main class and your Thread1 class do not share any variables or functions. They are separate classes.
Here's how I might do this:
class Main(QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setupUi(self)
self.initSetting()
self.initSignal()
def initSetting(self):
self.statusBar().showMessage("Wait")
self.setWindowTitle("aaaa")
def initSignal(self):
self.pushButton.clicked.connect(self.printWord)
def printWord(self):
self.statusBar().showMessage("Threading")
some_message = self.lineEdit.text().strip()
self.thread_1 = Thread1(some_message)
self.thread_1.start()
class Thread1(QThread):
def __init__(self, input_message, parent=None):
QThread.__init__(self, parent)
self.input_message = input_message
def run(self):
i = 1
while i <= 10:
print(self.input_message)
time.sleep(1)
i += 1
Let me know if this is helpful.
The issue that I'm facing is when I want to split the functionality of the menubar into multiple files (classes), each of them specific for handling options (File/Help/Edit and so on).
In the Main UI class I have:
class MyFrame(QMainWindow):
def __init__(self):
super().__init__()
self.menu_bar = self.menuBar()
# Create menu
self.add_menu()
def add_menu(self):
help_menu = MenuHelp(self)
def getMenuBar(self):
return self.menu_bar
In the MenuHelp (class):
class MenuHelp(QMenu):
def __init__(self, parrent_widget):
super(MenuHelp, self).__init__()
self.menu_variable = parrent_widget.getMenuBar().addMenu('Help')
about_action = self.menu_variable.addAction('About')
about_action.setStatusTip('About')
about_action.triggered.connect(self.handle_trigger)
def handle_trigger(self):
print('Im here')
The menubar is correctly shown, but handle_trigger method is never called, any ideas on what am I doing wrong?
You must pass a parent to your QMenu. You must change:
class MenuHelp(QMenu):
def __init__(self, parrent_widget):
super(MenuHelp, self).__init__()
to:
class MenuHelp(QMenu):
def __init__(self, parrent_widget):
super(MenuHelp, self).__init__(parrent_widget)
This is only a part of my code. When I clicked btn_convert or btn_save function (self.convertThread.start and self.convert_and_save) working. But when I clicked btn_convert_save, working only self.open. The question is, why after click on btn_convert_save starting not all 3 function ?
class Window(QtGui.QMainWindow):
def __init__(self):
super(Window, self).__init__() ...
def home(self):
self.saveThread = SaveThread()
self.convertThread = ConvertThread()
btn_convert.clicked.connect(self.convertThread.start)
btn_save.clicked.connect(self.saveThread.start)
btn_convert_save.clicked.connect(self.convert_and_save) ...
def convert_and_save(self):
self.open()
self.convertThread.start
self.saveThread.start
#self.convert()
#self.save_file()
class SaveThread(QtCore.QThread):
def __init__(self):
super(SaveThread, self).__init__()
def run(self):...
class ConvertThread(QtCore.QThread):
def __init__(self):
super(ConvertThread, self).__init__()
def run(self):...
you forgot the brackets, instead of
self.convertThread.start
write
self.convertThread.start()