Retrieve Variable From Class - python

I am trying to get the text variable from a QLineEdit widget that is created in a function within a class. Usually I would specify the class in which the variable was created for ex. var = classname.variable but this doesn't work in this case since the variable is created in a function in a class. Here is my code:
from PyQt5.QtWidgets import QWidget, QLineEdit, QApplication, QMainWindow
import sys
class main(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(0, 0, 200, 150)
line = QLineEdit(self)
line.resize(100, 21)
line.move(10, 35)
line.setText("the coolest text")
self.show()
text = main.line.text()
print(text)
if __name__ == "__main__":
app = QApplication(sys.argv)
gui = main()
sys.exit(app.exec())
How can I get this variable without putting all my code in one class?

Try it:
from PyQt5.QtWidgets import QWidget, QLineEdit, QApplication, QMainWindow
import sys
class main(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(0, 0, 270, 150)
self.line = QLineEdit(self)
self.line.resize(120, 21)
self.line.move(83, 35)
self.line.setText("the coolest text")
self.show()
# text = main.line.text()
# print(text)
if __name__ == "__main__":
app = QApplication(sys.argv) # +
gui = main()
# app = QApplication
text = gui.line.text() # +
print(text)
sys.exit(app.exec_())

Related

QWebEngineView history canGoForward/canGoBack works only after three items

I have a simple application where the back and forward buttons are enabled/disabled based on the history of the visited web pages. For this, I have found the canGoForward and canGoBack functions
of the QWebEngineHistory. However, the functions return True only after there are at least three items in the history. Normally, browsers work right after visiting the second different page.
Is this supposed to be working like that? I there any way to change it to the 2 web pages? I have looked at the QWebEngineSettings, but there is nothing related to this.
Here is a working example:
#!/usr/bin/python
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (QApplication, QLineEdit, QMainWindow,
QPushButton, QToolBar)
from PyQt5.QtWebEngineWidgets import QWebEnginePage, QWebEngineView
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.toolBar = QToolBar(self)
self.addToolBar(self.toolBar)
self.backBtn = QPushButton(self)
self.backBtn.setEnabled(False)
self.backBtn.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/left-32.png'))
# self.backBtn.setIcon(QIcon('stock_left.png'))
self.backBtn.clicked.connect(self.back)
self.toolBar.addWidget(self.backBtn)
self.forBtn = QPushButton(self)
self.forBtn.setEnabled(False)
# self.forBtn.setIcon(QIcon('stock_right.png'))
self.forBtn.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png'))
self.forBtn.clicked.connect(self.forward)
self.toolBar.addWidget(self.forBtn)
self.address = QLineEdit(self)
self.address.returnPressed.connect(self.load)
self.toolBar.addWidget(self.address)
self.webEngineView = QWebEngineView(self)
self.setCentralWidget(self.webEngineView)
self.webEngineView.page().urlChanged.connect(self.onLoadFinished)
print(self.webEngineView.history().backItem().url())
print(self.webEngineView.history().forwardItem().url())
self.setGeometry(300, 300, 500, 400)
self.setWindowTitle('QWebEnginePage')
self.show()
# self.webEngineView.page().urlChanged.connect(self.urlChanged)
def onLoadFinished(self):
print(dir(self.webEngineView.history()))
print('load finished')
# print(self.webEngineView.history().backItem().url())
# print(self.webEngineView.history().forwardItem().url())
# print(self.webEngineView.history().backItem())
# print(self.webEngineView.history().forwardItem())
# print(self.webEngineView.history().count())
# print(self.webEngineView.history().items())
# print(self.webEngineView.history().canGoForward())
# print(self.webEngineView.history().canGoBack())
if self.webEngineView.history().canGoBack():
self.backBtn.setEnabled(True)
else:
self.backBtn.setEnabled(False)
if self.webEngineView.history().canGoForward():
self.forBtn.setEnabled(True)
else:
self.forBtn.setEnabled(False)
def load(self):
url = QUrl.fromUserInput(self.address.text())
if url.isValid():
self.webEngineView.load(url)
def back(self):
self.webEngineView.page().triggerAction(QWebEnginePage.Back)
def forward(self):
self.webEngineView.page().triggerAction(QWebEnginePage.Forward)
def urlChanged(self, url):
self.address.setText(url.toString())
def main():
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

How to remove a Qlabel in PyQt5

I have already read some answers but they do not work for me.
This is my code:
from PyQt5.QtWidgets import QWidget, QCheckBox, QApplication, QHBoxLayout, QLabel
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
import sys
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
cbAll = QCheckBox('Slice 1', self) # Slice 1
cbAll.move(1200, 130)
cbAll.toggle()
cbAll.stateChanged.connect(self.OpenSlice1)
self.setGeometry(0, 25, 1365, 700)
self.setWindowTitle('Original Slices')
self.show()
def OpenSlice1(self,state):
pixmap = QPixmap("E:\BEATSON_PROJECT\python\GUI\home.png")
self.lbl = QLabel(self) #Qlabel used to display QPixmap
self.lbl.setPixmap(pixmap)
if state == Qt.Checked:
self.lbl.show()
else:
self.lbl.hide()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
However when it goes into the unchecked option it does not hide the image:
Original window:
Checked Slice 1 window:
From this point on it always shows the image and I want it to hide it. i.e unckecking the box does not work:
The problem is caused because each time you press you are creating a new QLabel and you assign the same variable so you lose access to that element, and then you are closing the new QLabel, but not the old one. What you must do is create it and only hide it for it you could use the setVisible() or hide() and show() method.
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
cbAll = QCheckBox('Slice 1', self) # Slice 1
cbAll.move(1200, 130)
cbAll.toggle()
cbAll.stateChanged.connect(self.OpenSlice1)
pixmap = QPixmap("E:\BEATSON_PROJECT\python\GUI\home.png")
self.lbl = QLabel(self) #Qlabel used to display QPixmap
self.lbl.setPixmap(pixmap)
self.setGeometry(0, 25, 1365, 700)
self.setWindowTitle('Original Slices')
self.show()
def OpenSlice1(self, state):
self.lbl.setVisible(state != Qt.Unchecked)
# or
"""if state == Qt.Checked:
self.lbl.show()
else:
self.lbl.hide()"""

How can I dynamically add/remove elements in an element?

Here's my code. I'm trying to make it such that as you change the dropdown box, it will dynamically show more or less QLineEdits for input. This is just the latest iteration of testing
import sys
from PyQt5.QtWidgets import (QWidget, QPushButton, QLineEdit,
QInputDialog, QApplication, QComboBox, QFrame)
import numpy as np
class GUI(QWidget):
def __init__(self):
super().__init__()
self.initgui()
def initgui(self):
#
# Set up GUI
#
self.setGeometry(100, 100, 400, 400)
self.move(300, 300)
combobox = QComboBox(self)
for i in range(1, 10, 1):
combobox.addItem(str(i + 1))
combobox.activated[str].connect(self.comboboxchanged)
self.setWindowTitle("Testing Easy Setup")
self.show()
def comboboxchanged(self, text):
frame = QWidget(self)
frame.hide()
for num in range(0, int(text), 1):
QLineEdit(frame).move(60, num * 19)
frame.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
gui = GUI()
sys.exit(app.exec_())
The problem is that when you pass a parent to a widget it is placed in the 0, 0 position with respect to the parent, in your case QFrame is on top of QComboBox since both are in the 0, 0 position. The proper thing is to use layouts. On the other hand you have to eliminate the widgets before adding new ones for it, we create a function that eliminates those items.
import sys
from PyQt5.QtWidgets import *
def clearLayout(lay):
while lay.count() > 0:
item = lay.takeAt(0)
widget = item.widget()
if widget:
widget.deleteLater()
del item
class GUI(QWidget):
def __init__(self):
super().__init__()
self.initgui()
def initgui(self):
lay = QHBoxLayout(self)
vlay1 = QVBoxLayout()
combobox = QComboBox(self)
combobox.addItems([str(i) for i in range(2, 11)])
vlay1.addWidget(combobox)
vlay1.addItem(QSpacerItem(20, 245, QSizePolicy.Minimum, QSizePolicy.Expanding))
self.vlay2 = QVBoxLayout()
lay.addLayout(vlay1)
lay.addLayout(self.vlay2)
self.comboboxchanged(combobox.currentText())
combobox.activated[str].connect(self.comboboxchanged)
self.setWindowTitle("Testing Easy Setup")
self.show()
def comboboxchanged(self, text):
clearLayout(self.vlay2)
for num in range(0, int(text)):
self.vlay2.addWidget(QLineEdit(self))
self.vlay2.addItem(QSpacerItem(20, 245, QSizePolicy.Minimum, QSizePolicy.Expanding))
if __name__ == '__main__':
app = QApplication(sys.argv)
gui = GUI()
sys.exit(app.exec_())

Call setCentralWidget from other file

I have different files (main.py and layout.py) and I want to change the windows (I have shortened the example that it should change the window size) of QMainWindow from the file layout.py.
It works fine from main.py, I can change the windows from the file main.py, but it has no effect in layout.py.
UPDATE: I changed the files two a working example with the problem that the Button "Switch to Layout 2" does not work.
main.py
import sys
from PyQt5.QtWidgets import QAction, QApplication, QMainWindow
from layout import Layout1, Layout2
class MainClass(QMainWindow):
def __init__(self):
super(MainClass, self).__init__()
def initUI(self):
self.setGeometry(50, 100, 600, 500)
self.setWindowTitle('program')
self.window1Action = QAction('Window1', self)
self.window1Action.triggered.connect(self.window1)
self.window2Action = QAction('Window2', self)
self.window2Action.triggered.connect(self.window2)
self.menubar = self.menuBar()
menu = self.menubar.addMenu('&Menu')
menu.addAction(self.window1Action)
menu.addAction(self.window2Action)
self.show()
def window1(self):
wsize1 = (1200, 600)
self.resize(*wsize1)
self.form_widget = Layout1()
self.setCentralWidget(self.form_widget)
def window2(self):
wsize2 = (600, 500)
self.resize(*wsize2)
self.form_widget = Layout2()
self.setCentralWidget(self.form_widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MainClass()
ex.initUI()
sys.exit(app.exec_())
layout.py
from PyQt5.QtWidgets import QFormLayout, QPushButton, QWidget
class Layout1(QWidget):
def __init__(self, parent=None):
super(Layout1, self).__init__(parent)
self.form_layout = QFormLayout(self)
self.button1 = QPushButton('Button1')
self.form_layout.addRow('nonfunctional', self.button1)
self.buttonX = QPushButton('Switch to Layout2')
self.form_layout.addRow('Problem', self.buttonX)
self.buttonX.clicked.connect(self.change_layout)
self.setLayout(self.form_layout)
def change_layout(self):
from main import MainClass
self.change_window = MainClass()
self.change_window.window2()
class Layout2(QWidget):
def __init__(self, parent=None):
super(Layout2, self).__init__(parent)
self.form_layout = QFormLayout(self)
self.button2 = QPushButton('Button3')
self.form_layout.addRow('nonfunctional', self.button2)
self.setLayout(self.form_layout)
Can anybody explain to me what I have done wrong?
Your Layout classes have a parent parameter, so use it. You need to get a reference to the existing instance of the main window, not create a new one:
def window1(self):
...
self.form_widget = Layout1(self)
self.setCentralWidget(self.form_widget)
...
def change_layout(self):
self.parent().window2()

PyQt5 button to run function and update LCD

I am getting started with creating GUI's in PyQt5 with Python 3. At the click of the button I want to run the "randomint" function and display the returned integer to the QLCDNumber named "lcd".
Here's my code:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLCDNumber
from random import randint
class Window(QWidget):
def __init__(self):
super().__init__()
self.initui()
def initui(self):
lcd = QLCDNumber(self)
button = QPushButton('Generate', self)
button.resize(button.sizeHint())
layout = QVBoxLayout()
layout.addWidget(lcd)
layout.addWidget(button)
self.setLayout(layout)
button.clicked.connect(lcd.display(self.randomint()))
self.setGeometry(300, 500, 250, 150)
self.setWindowTitle('Rand Integer')
self.show()
def randomint(self):
random = randint(2, 99)
return random
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Window()
sys.exit(app.exec_())
I am getting the output:
TypeError: argument 1 has unexpected type 'NoneType'
How can I get the LCD to display the output from function "randomint"?
The problem is that the button.clicked.connect expects the slot (Python callable object), but lcd.display returns None. So we need a simple function (slot) for button.clicked.connect which will display your newly generated value. This is working version:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLCDNumber
from random import randint
class Window(QWidget):
def __init__(self):
super().__init__()
self.initui()
def initui(self):
self.lcd = QLCDNumber(self)
button = QPushButton('Generate', self)
button.resize(button.sizeHint())
layout = QVBoxLayout()
layout.addWidget(self.lcd)
layout.addWidget(button)
self.setLayout(layout)
button.clicked.connect(self.handleButton)
self.setGeometry(300, 500, 250, 150)
self.setWindowTitle('Rand Integer')
self.show()
def handleButton(self):
self.lcd.display(self.randomint())
def randomint(self):
random = randint(2, 99)
return random
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Window()
sys.exit(app.exec_())
Another way of resolving the TypeError: argument 1 has unexpected type 'NoneType is to prefix your slot with lambda: like so:
self.tableWidget.cellChanged['int','int'].connect(lambda:self.somefunction())
I actually don't know why but it's a solution that worked for me.

Categories

Resources