This question already has answers here:
change label from other class in a different file
(2 answers)
Closed 3 years ago.
How to update a Widget from Window A in Window B?
I have a widget that i want to change in my second window, how would i proceed from here?
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
#MyWidget
...
def openSecond(self):
self.SW = SecondWindow(#MyWidget)
self.SW.show()
class SecondWindow(QMainWindow):
def __init__(self, #MyWidget):
super(SecondWindow, self).__init__()
#MyWidget.changed
#Update to parent
...
Pass the self from class A as Argument when creating an instance of the class B, then you can access the items from class A in class B with self.parent.
from PySide2.QtWidgets import QMainWindow, QPushButton, QApplication, QLabel
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.button = ''
btn = QPushButton('Open Second', self)
btn.move(10, 10)
btn.clicked.connect(self.openSecond)
self.resize(420, 450)
button = QPushButton(self)
button.move(100,100)
button.setText("current text")
self.button = button
def openSecond(self):
self.SW = SecondWindow(self.button, parent=self)
self.SW.show()
class SecondWindow(QMainWindow):
def __init__(self, button, parent=None):
super(SecondWindow, self).__init__()
self.parent = parent
lbl = QLabel('Second Window', self)
button.setText("updated text")
self.parent.buttons = button
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
MW = MainWindow()
MW.show()
sys.exit(app.exec_())
Related
I am new to the world of pyqt5 I have created a window using this code:
class Ui_menu(QtWidgets.QMainWindow):
def __init__(self):
super(Ui_menu, self).__init__() # Call the inherited classes __init__ method
uic.loadUi('Windows/menu.ui', self) # Load the .ui file
self.show()
app = QtWidgets.QApplication(sys.argv)
window = Ui_menu()
app.exec_()
I want to know if you can create an animation when you click a button at the top and open a floating window as in the attached image.
look this code
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QSize, QPoint, Qt
from PyQt5.QtGui import QIcon
class MyProxyStyle(QProxyStyle):
pass
def pixelMetric(self, QStyle_PixelMetric, option=None, widget=None):
if QStyle_PixelMetric == QStyle.PM_SmallIconSize:
return 100
else:
return QProxyStyle.pixelMetric(self, QStyle_PixelMetric, option, widget)
class main(QMainWindow):
def __init__(self):
super().__init__()
self.central = QWidget()
self.toolbar = toolbar()
self.button1 = toolbutton("your_icon")
self.button2 = toolbutton("your_icon")
self.toolbar.addWidget(self.button1)
self.toolbar.addWidget(self.button2)
self.button1.clicked.connect(lambda: self.open_menu(self.button1))
self.button2.clicked.connect(lambda: self.open_menu(self.button2))
self.addToolBar(Qt.ToolBarArea.TopToolBarArea, self.toolbar)
self.setCentralWidget(self.central)
self.resize(600,400)
self.show()
def open_menu(self, obj):
self.menu = QMenu()
self.menu.setStyle(MyProxyStyle())
self.menu.addAction(QIcon("your_icon"), "Person")
self.menu.addMenu("Configuration")
self.menu.addSeparator()
self.menu.addMenu("Profile")
pos = self.mapToGlobal(QPoint(obj.x(), obj.y()+obj.height()))
self.menu.exec(pos)
class toolbar(QToolBar):
def __init__(self):
super().__init__()
self.setIconSize(QSize(80,80))
self.setMinimumHeight(80)
self.setMovable(False)
class toolbutton(QToolButton):
def __init__(self, icon):
super().__init__()
self.setIcon(QIcon(icon))
self.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
app = QApplication([])
window = main()
app.exec()
I am having problems with sending data from one QWizard page to the next. I'm using a variable my_name of QWizard object as a container.
My approach is: whenever I change text of QLineEdit on Page1, the variable my_name of my QWizard object changes. And whenever I click Next button on Page1, Page2 is initialized using the method QWizard.initializePage(2). But the QLabel object on Page2 is not update based on the my_name variable of QWizard object. Even though I have initialized the Page2 also. What is wrong with my approach?
My code is:
import sys
from PyQt5.QtWidgets import *
class Window(QWizard):
def __init__(self):
super(Window, self).__init__()
self.firstPage = MainPage(parent=self)
self.my_name = 'Random'
self.secondPage = Page2(parent=self)
self.addPage(self.firstPage)
self.button(QWizard.NextButton).clicked.connect(lambda: self.initializePage(2))
self.addPage(self.secondPage)
class MainPage(QWizardPage):
def __init__(self, parent=None):
self.Parent = parent
super(MainPage, self).__init__(parent)
self.setTitle("Plz input your name?")
self.NameLabel = QLabel("&Name:")
self.NameLineEdit = QLineEdit()
self.NameLineEdit.textChanged.connect(self.assign)
self.NameLabel.setBuddy(self.NameLineEdit)
layout = QHBoxLayout()
layout.addWidget(self.NameLabel)
layout.addWidget(self.NameLineEdit)
self.setLayout(layout)
def assign(self):
self.Parent.my_name = self.NameLineEdit.text()
print(f'Parent text is: {self.Parent.my_name}')
class Page2(QWizardPage):
def __init__(self, parent=None):
super(Page2, self).__init__()
self.Parent = parent
vbox = QVBoxLayout()
label = QLabel()
label.setText(f'My name is : {self.Parent.my_name}')
vbox.addWidget(label)
self.setLayout(vbox)
def main():
app = QApplication(sys.argv)
app.setStyle('plastique')
window = Window()
window.setWizardStyle(1)
window.show()
app.exec_()
if __name__ == "__main__":
sys.exit(main())
Changing the value of the variable "my_name" does not change what the QLabel shows since QLabel copies the text. On the other hand you should not call initializePage(2) since it is a protected method that is called internally. The solution is to override the initializePage method of the QWizardPage:
class Page2(QWizardPage):
def __init__(self, parent=None):
super(Page2, self).__init__()
self.Parent = parent
vbox = QVBoxLayout(self)
self.label = QLabel()
self.label.setText(f'My name is : {self.Parent.my_name}')
vbox.addWidget(self.label)
def initializePage(self):
self.label.setText(f'My name is : {self.Parent.my_name}')
Although I see that you are reinventing the wheel since there is already that characteristic registering the fields:
class Window(QWizard):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.firstPage = MainPage()
self.secondPage = Page2()
self.addPage(self.firstPage)
self.addPage(self.secondPage)
class MainPage(QWizardPage):
def __init__(self, parent=None):
super(MainPage, self).__init__(parent)
self.setTitle("Plz input your name?")
self.NameLabel = QLabel("&Name:")
self.NameLineEdit = QLineEdit()
self.NameLabel.setBuddy(self.NameLineEdit)
layout = QHBoxLayout(self)
layout.addWidget(self.NameLabel)
layout.addWidget(self.NameLineEdit)
self.registerField("my_name", self.NameLineEdit)
class Page2(QWizardPage):
def __init__(self, parent=None):
super(Page2, self).__init__(parent)
vbox = QVBoxLayout(self)
self.label = QLabel()
vbox.addWidget(self.label)
def initializePage(self):
self.label.setText(f'My name is : {self.field("my_name")}')
super(Page2, self).initializePage()
I am lost with all the parenting/initialising issues and have no idea why this does not work.
So I create a Label, then I create another Label with some painting in it, them I make a widget that contains the two, then I would like to put this new widget inside the main window... but nothing appears
import sys
import os
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Labhtml(QLabel):
def __init__(self):
super().__init__()
label = QLabel('html')
class Bar(QLabel):
def __init__(self):
super().__init__()
self.resize(100, 5)
def paintEvent(self, e):
qp = QPainter(self)
qp.setBrush(QColor(200, 0, 0))
qp.drawRect(0,0,200,3)
class Wid(QWidget):
def __init__(self, parent):
super().__init__(parent=parent)
widget = QWidget()
html = Labhtml()
bar = Bar()
self.layout = QVBoxLayout(widget)
self.layout.addWidget(html)
self.layout.addWidget(bar)
class Example(QScrollArea):
def __init__(self):
super().__init__()
widget = QWidget()
layout = QVBoxLayout(widget)
layout.addWidget(Wid(widget))
self.setWidget(widget)
self.setWidgetResizable(True)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
First for the class Labhtml, when you inherit from QLabel, you can use the methods and the attributes of the base class, or use the instantiation mechanism to pass some parameters :
class Labhtml(QLabel):
def __init__(self):
super().__init__()
self.setText('html')
Then you don't need to create another widget inside the Wid class, but you have to refer to self instead :
class Wid(QWidget):
def __init__(self, parent):
super().__init__(parent=parent)
html = Labhtml()
bar = Bar()
self.layout = QVBoxLayout(self)
self.layout.addWidget(html)
self.layout.addWidget(bar)
About the instantiation mechanism you could also write the classes by declaring a new text argument (the same used for the Qlabel), and pass it when you create your instance :
class Labhtml(QLabel):
def __init__(self, text):
super().__init__(text)
class Wid(QWidget):
def __init__(self, parent):
super().__init__(parent=parent)
html = Labhtml('html')
Here I have a QMainWindow and QWidget class
class WifiHotspot(QMainWindow):
def __init__(self, parent=None):
super(WifiHotspot, self).__init__(parent)
self.title = 'WIFI HOTSPOT'
self.initUI()
def initUI(self):
self.virtual_wifi = VirtualWifi(self)
self.setCentralWidget(self.virtual_wifi)
# i want to dynamic set statusBar in VirtualWifi class
#self.statusBar().showMessage('message here') # it work only in WifiHotspot
self.setWindowTitle(self.title)
self.show()
class VirtualWifi(QWidget):
def __init__(self, parent):
super (VirtualWifi, self).__init__(parent)
self.initVirtualWifi()
def initVirtualWifi(self):
startButton = QPushButton('Start', self)
startButton.setToolTip('Start sharing wifi')
// when click
startButton.clicked.connect(self.start_hotspot)
#pyqtSlot()
def start_hotspot(self):
# show message in statusBar in QMainWindow
How can I show a statusBar message in WifiHotspot when click startButton from VirtualWifi
Here is an answer
** Answers:
Create a set_status_message in WifiHotspot
def set_status_message(self, message):
return self.statusBar().showMessage(message)
Call it from start_hotspot(self)
def start_hotspot(self):
self.parent().set_status_message('hello world')
I want to get a string from the main window to use in a window triggered with a click. I know how to do it by putting all statements into a single class, but now I'm trying to do the same thing with one class per window. Here is the code:
import sys
from PyQt4 import QtGui
class Window(QtGui.QWidget):
def __init__(self, parent=None):
super().__init__()
self.initUI()
def initUI(self):
self.value = QtGui.QLineEdit('23')
self.button = QtGui.QPushButton('Open Dialog')
self.button.clicked.connect(self.openDialog)
vbox = QtGui.QVBoxLayout()
vbox.addWidget(self.value)
vbox.addWidget(self.button)
self.setLayout(vbox)
def openDialog(self):
self.entry = self.value.text()
print(self.entry)
Dialog().exec_()
class Dialog(QtGui.QDialog):
def __init__(self, parent=Window):
super().__init__()
win = Window()
self.text = win.entry
self.label = QtGui.QLabel(self.text)
hbox = QtGui.QHBoxLayout()
hbox.addWidget(self.label)
self.setLayout(hbox)
def main():
app = QtGui.QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
But I'm getting the error "AttributeError: 'Window' object has no attribute 'entry'" and I don't know any other way to try fix it. Can someone help me with it?
Create an instance of Dialog in the openDialog method, so that you can access its attributes directly. That way, the two classes can operate more independently, and you won't need to access the Window class from within the Dialog class:
def openDialog(self):
dialog = Dialog(self)
dialog.label.setText(self.value.text())
dialog.exec_()
print(dialog.label.text())
class Dialog(QtGui.QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.label = QtGui.QLabel(self)
hbox = QtGui.QHBoxLayout()
hbox.addWidget(self.label)
self.setLayout(hbox)
Here
win = Window()
self.text = win.entry
you declare a new window and accesing its entry field but on your window class
class Window(QtGui.QWidget):
def __init__(self, parent=None):
super().__init__()
self.initUI()
the entry field is not constructed.
So
Either you want to create a new window, so you have to put the self.entry on the constructor
You want to use the existing window an access its entry after calling openDialog
Edit:
Maybe here
class Dialog(QtGui.QDialog):
def __init__(self, parent=Window):
super().__init__()
you are initializing the class wrong. The parent constructor should be called with parent=Window too. Then from inside the dialog you could reference the window by doing self.parent