PyQt5 - resize (limit maximum size) input dialog - python

I read this: How to resize QInputDialog, PyQt but it didnt work for me, as it seems to be about PyQt4
This is my code snipplet:
def ImportURL(self): #URL dialog aufrufen
InputDialog = QtWidgets.QInputDialog(self)
i, okPressed = InputDialog.getText(self, "Import website", "Site to import:", QtWidgets.QLineEdit.Normal, "https://de.wikipedia.org/wiki/Wikipedia:Hauptseite")
if okPressed:
self.getWebsite(i)
And i tried adding .setFixedSize in the 2nd line. I tried adding InputDialog.setFixedSite(self) between line 2 and 3. Nothing worked, it either crashes or it creates a second, empty window. Am i overlooking something here?

In the answers to the other question do not explain the cause of the problem so in my answer will try to cover as much as possible
Explanation:
The getText() method is a static method, which means that an object is not used, in the method internally if it is used but it is not accessible. So the InputDialog that you create is not the one you show and this you can check using the following code since you will see 2 windows:
def ImportURL(self):
InputDialog = QtWidgets.QInputDialog(self)
InputDialog.show()
i, okPressed = InputDialog.getText(self, "Import website", "Site to import:", QtWidgets.QLineEdit.Normal, "https://de.wikipedia.org/wiki/Wikipedia:Hauptseite")
if okPressed:
self.getWebsite(i)
Solutions:
So there are the following solutions:
Taking advantage of what you have passed as a parent to self, you can obtain the object using findChildren:
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
button = QtWidgets.QPushButton(
"Open QInputDialog", clicked=self.ImportURL
)
vlay = QtWidgets.QVBoxLayout(self)
vlay.addWidget(button)
#QtCore.pyqtSlot()
def ImportURL(self):
QtCore.QTimer.singleShot(0, self.after_show)
i, okPressed = QtWidgets.QInputDialog.getText(
self,
"Import website",
"Site to import:",
QtWidgets.QLineEdit.Normal,
"https://de.wikipedia.org/wiki/Wikipedia:Hauptseite",
)
if okPressed:
# self.getWebsite(i)
print(i)
#QtCore.pyqtSlot()
def after_show(self):
size = QtCore.QSize(500, 100)
for d in self.findChildren(QtWidgets.QInputDialog):
if d.isVisible():
d.resize(size)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
Do not use the getText() method but create an object that implements the same logic:
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
button = QtWidgets.QPushButton(
"Open QInputDialog", clicked=self.ImportURL
)
vlay = QtWidgets.QVBoxLayout(self)
vlay.addWidget(button)
#QtCore.pyqtSlot()
def ImportURL(self):
dialog = QtWidgets.QInputDialog(self)
dialog.resize(QtCore.QSize(500, 100))
dialog.setWindowTitle("Import website")
dialog.setLabelText("Site to Import")
dialog.setTextValue(
"https://de.wikipedia.org/wiki/Wikipedia:Hauptseite"
)
dialog.setTextEchoMode(QtWidgets.QLineEdit.Normal)
if dialog.exec_() == QtWidgets.QDialog.Accepted:
i = dialog.textValue()
print(i)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
Update:
The layout of the QInputDialog has QLayout::SetMinAndMaxSize set as sizeConstraint, so the fixed size will not work, the trick is to change it to QLayout::SetDefaultConstraint:
from functools import partial
# ...
#QtCore.pyqtSlot()
def ImportURL(self):
dialog = QtWidgets.QInputDialog(self)
dialog.setWindowTitle("Import website")
dialog.setLabelText("Site to Import")
dialog.setTextValue(
"https://de.wikipedia.org/wiki/Wikipedia:Hauptseite"
)
dialog.setTextEchoMode(QtWidgets.QLineEdit.Normal)
wrapper = partial(self.on_timeout, dialog)
QtCore.QTimer.singleShot(0, wrapper)
if dialog.exec_() == QtWidgets.QDialog.Accepted:
i = dialog.textValue()
print(i)
def on_timeout(self, dialog):
lay = dialog.layout()
lay.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
dialog.setFixedSize(QtCore.QSize(500, 100))

Related

How to print test output to a label in pyqt gui

what I am trying to do with a python script: Use a pytest test method to print a text line to a label in the pyqt GUI.
When running the main python file, the GUI starts and a click on the "test" button runs the test without blocking the GUI (see full code example below). But I have no clue how to proceed now.
Code:
import sys
import pytest
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget
class Window(QtWidgets.QMainWindow):
signal_start_background_job = QtCore.pyqtSignal()
def __init__(self):
super(Window, self).__init__()
layout = QVBoxLayout()
self.button = QtWidgets.QPushButton("test", self)
self.label = QtWidgets.QLabel("console output")
layout.addWidget(self.button)
layout.addWidget(self.label)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
self.worker = WorkerObject()
self.thread = QtCore.QThread()
self.worker.moveToThread(self.thread)
self.signal_start_background_job.connect(self.worker.background_job)
self.button.clicked.connect(self.start_background_job)
def start_background_job(self):
self.thread.start()
self.signal_start_background_job.emit()
class WorkerObject(QtCore.QObject):
#QtCore.pyqtSlot()
def background_job(self):
pytest.main(["-s", "-k test_something"])
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
def test_something():
print("unit test some stuff")
assert 0 == 0
Instead of using pytest directly you could use QProcess to launch it and then capture the output:
import os
import sys
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
class Window(QtWidgets.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.button = QtWidgets.QPushButton("test", self)
self.label = QtWidgets.QLabel("console output")
self.textedit = QtWidgets.QTextEdit(readOnly=True)
widget = QWidget()
layout = QVBoxLayout(widget)
layout.addWidget(self.button)
layout.addWidget(self.label)
layout.addWidget(self.textedit)
self.setCentralWidget(widget)
self.process = QtCore.QProcess()
self.process.setProgram(sys.executable)
self.process.readyReadStandardError.connect(self.on_readyReadStandardError)
self.process.readyReadStandardOutput.connect(self.on_readyReadStandardOutput)
self.button.clicked.connect(self.on_clicked)
#QtCore.pyqtSlot()
def on_clicked(self):
self.process.setWorkingDirectory(CURRENT_DIR)
self.process.setArguments(["-m", "pytest", "-s", "-k", "test_something"])
self.process.start()
#QtCore.pyqtSlot()
def on_readyReadStandardError(self):
err = self.process.readAllStandardError().data().decode()
self.textedit.append(err)
#QtCore.pyqtSlot()
def on_readyReadStandardOutput(self):
out = self.process.readAllStandardOutput().data().decode()
self.textedit.append(out)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
I'm thinking you need to check out sys.stdout, and route that to an io object that you can route to the label in your widget. Then I would set a timer and every 0.1 seconds or so set the text of your label to that object. Alternatively you can implement a widget that grabs the stdout text in qt, example here: https://stackoverflow.com/a/1220002/6615517 I haven't tried it but the other answers to that question should help. You'll probably want to clear the label on each test to prevent it from getting too long.

QFileDialog.getOpenFileName change button text from 'Open' to 'Remove'

I am using QFileDialog.getOpenFileName(self,'Remove File', "path", '*.pdf') to select a file and get the path in order to remove it from my application. The issue is the QFileDialog.getOpenFileName window button says 'Open' when selecting a file which will be confusing to the user.
Is there any way to change the button text from 'Open' to 'Remove'/'Delete'
When using the static method QFileDialog::getOpenFileName() the first thing is to obtain the QFileDialog object and for that we use a QTimer and the findChild() method:
# ...
QtCore.QTimer.singleShot(0, self.on_timeout)
filename, _ = QtWidgets.QFileDialog.getOpenFileName(...,
options=QtWidgets.QFileDialog.DontUseNativeDialog)
def on_timeout(self):
dialog = self.findChild(QtWidgets.QFileDialog)
# ...
Then you can get the text iterating over the buttons until you get the button with the searched text and change it:
for btn in dialog.findChildren(QtWidgets.QPushButton):
if btn.text() == "&Open":
btn.setText("Remove")
That will work at the beginning but every time you interact with the QTreeView they show, update the text to the default value, so the same logic will have to be applied using the currentChanged signal from the selectionModel() of the QTreeView but for synchronization reasons it is necessary Update the text later using another QTimer.singleShot(), the following code is a workable example:
import sys
from PyQt5 import QtCore, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
button = QtWidgets.QPushButton("Press me")
button.clicked.connect(self.on_clicked)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(button)
#QtCore.pyqtSlot()
def on_clicked(self):
QtCore.QTimer.singleShot(0, self.on_timeout)
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
self,
"Remove File",
"path",
"*.pdf",
options=QtWidgets.QFileDialog.DontUseNativeDialog,
)
def on_timeout(self):
dialog = self.findChild(QtWidgets.QFileDialog)
dialog.findChild(QtWidgets.QTreeView).selectionModel().currentChanged.connect(
lambda: self.change_button_name(dialog)
)
self.change_button_name(dialog)
def change_button_name(self, dialog):
for btn in dialog.findChildren(QtWidgets.QPushButton):
if btn.text() == self.tr("&Open"):
QtCore.QTimer.singleShot(0, lambda btn=btn: btn.setText("Remove"))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
The first step can be avoided if the static method is not used and create the dialog using an instance of QFileDialog:
import sys
from PyQt5 import QtCore, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
button = QtWidgets.QPushButton("Press me")
button.clicked.connect(self.on_clicked)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(button)
#QtCore.pyqtSlot()
def on_clicked(self):
dialog = QtWidgets.QFileDialog(
self,
"Remove File",
"path",
"*.pdf",
supportedSchemes=["file"],
options=QtWidgets.QFileDialog.DontUseNativeDialog,
)
self.change_button_name(dialog)
dialog.findChild(QtWidgets.QTreeView).selectionModel().currentChanged.connect(
lambda: self.change_button_name(dialog)
)
if dialog.exec_() == QtWidgets.QDialog.Accepted:
filename = dialog.selectedUrls()[0]
print(filename)
def change_button_name(self, dialog):
for btn in dialog.findChildren(QtWidgets.QPushButton):
if btn.text() == self.tr("&Open"):
QtCore.QTimer.singleShot(0, lambda btn=btn: btn.setText("Remove"))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
While I appreciate the solution provided by #eyllanesc, I'd like to propose a variation.
Under certain circumstances, the code for that answer might fail, specifically:
the delay that X11 suffers from mapping windows;
the checking of localized button strings;
the selection using the file name edit box;
Considering the above, I propose an alternate solution, based on the points above.
For obvious reasons, the main point remains: the dialog must be non-native.
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class FileDialogTest(QWidget):
def __init__(self):
super().__init__()
layout = QHBoxLayout(self)
self.fileEdit = QLineEdit()
layout.addWidget(self.fileEdit)
self.selectBtn = QToolButton(icon=QIcon.fromTheme('folder'), text='…')
layout.addWidget(self.selectBtn)
self.selectBtn.clicked.connect(self.showSelectDialog)
def checkSelectDialog(self):
dialog = self.findChild(QFileDialog)
if not dialog.isVisible():
# wait for dialog finalization, as testOption might fail
return
# dialog found, stop the timer and delete it
self.sender().stop()
self.sender().deleteLater()
if not dialog.testOption(dialog.DontUseNativeDialog):
# native dialog, we cannot do anything!
return
def updateOpenButton():
selection = tree.selectionModel().selectedIndexes()
if selection and not tree.model().isDir(selection[0]):
# it's a file, change the button text
button.setText('Select my precious file')
tree = dialog.findChild(QTreeView)
button = dialog.findChild(QDialogButtonBox).button(
QDialogButtonBox.Open)
# check for selected files on open
updateOpenButton()
# connect the selection update signal
tree.selectionModel().selectionChanged.connect(
lambda: QTimer.singleShot(0, updateOpenButton))
def showSelectDialog(self):
QTimer(self, interval=10, timeout=self.checkSelectDialog).start()
path, filter = QFileDialog.getOpenFileName(self,
'Select file', '<path_to_file>',
"All Files (*);;Python Files (*.py);; PNG Files (*.png)",
options=QFileDialog.DontUseNativeDialog)
if path:
self.fileEdit.setText(path)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
ex = FileDialogTest()
ex.show()
sys.exit(app.exec())
Obviously, for PyQt6 you'll need to use the proper Enum namespaces (i.e. QFileDialog.Option.DontUseNativeDialog, etc.).

How do I get a signal from a QWiget to change get object?

Hello I have a QWidget and If I click on it, I want to get the object (the QWidget Element I clicked on) is there anyway to do that?
I already found some code but I only get the MouseClickEvent from
self.widget_34.mouseReleaseEvent = lambda event: self.myfunction(event)
Although the solution offered by #Cin is interesting, it has a serious problem: it cancels the mousePressEvent of the widget, so the widget loses the behavior it could have when the widget is pressed, for example the button no longer emits the clicked signal, other widget also They will have the same problem.
A less intrusive solution is to use eventFilter:
import sys
import weakref
from PyQt5 import QtCore, QtWidgets
class ClickListener(QtCore.QObject):
clicked = QtCore.pyqtSignal(QtWidgets.QWidget)
def addWidget(self, widget, other_widget=None):
if not hasattr(self, "_widgets"):
self._widgets = {}
widget.installEventFilter(self)
self._widgets[widget] = widget if other_widget is None else other_widget
weakref.ref(widget, self.removeWidget)
def eventFilter(self, obj, event):
if (
obj in self._widgets
and event.type() == QtCore.QEvent.MouseButtonPress
):
self.clicked.emit(self._widgets[obj])
return super(ClickListener, self).eventFilter(obj, event)
def removeWidget(self, widget):
if hasattr(self, "_widgets"):
if widget in self._widgets:
del self._widgets[widget]
class App(QtWidgets.QWidget):
def __init__(self):
super().__init__()
button = QtWidgets.QPushButton("Press Me")
label = QtWidgets.QLabel("Stack Overflow")
spinBox = QtWidgets.QSpinBox()
te = QtWidgets.QTextEdit()
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(button)
lay.addWidget(label)
lay.addWidget(spinBox)
lay.addWidget(te)
listener = ClickListener(self)
listener.clicked.connect(self.onClicked)
listener.addWidget(button)
listener.addWidget(label)
listener.addWidget(spinBox.lineEdit(), spinBox)
listener.addWidget(te.viewport(), te)
def onClicked(self, obj):
print("Clicked, from", obj)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
I am not sure this will be a proper solution or not but I think, you can use the partial method of functools module. A collable object can be treated as a function for the purposes of this module. Here you can see my example,
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel
import functools
class App(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(200,200,200,200)
self.button = QPushButton('Button', self)
self.button.move(50,50)
self.label = QLabel(self)
self.label.setText("Label")
self.label.move(100,100)
self.items = [self.button, self.label]
for i in self.items:
i.mousePressEvent = functools.partial(self.getClickedItem, source_object=i)
self.show()
def getClickedItem(self, event, source_object=None):
print("Clicked, from", source_object)
#item text
#print(source_object.text())
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())

How can I inherit between classes in pyqt?

In order to track progress, this is the third question about practicing with different classes in PyQt5 .Here are the links to my previous questions:opening a new window, Open a file from main window to a new window in PyQt5 (in different files).
I'm trying to work with two classes, one with one button and when it's pressed it will load a file and show the text in a QTextEdit in other class.
In the first questions I was suggested that as an alternative to work with more classes, they can inherit from QMainWindow so I looked for more info for doing this: PyQt class inheritance
The second question code did worked but it would show both windows at the same time, so this question: PyQt: How to hide QMainWindow guided me to write this code (I attatch this here because it's a little bit different from the one in the link, plus I apply what it says in the answer):
import sys, os
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
class Dialog_02(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Dialog_02, self).__init__(parent, QtCore.Qt.Window)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
myBoxLayout = QVBoxLayout()
Button_02 = QPushButton ("Show Dialog 01")
myBoxLayout.addWidget(Button_02)
self.setLayout(myBoxLayout)
self.setWindowTitle('Dialog 02')
Button_02.clicked.connect(self.closeAndReturn)
def closeAndReturn(self):
self.close()
self.parent().show()
class Dialog_01(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Dialog_01, self).__init__()
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
myBoxLayout = QVBoxLayout()
Button_01 = QPushButton ("Show Dialog 02")
myBoxLayout.addWidget(Button_01)
self.setLayout(myBoxLayout)
self.setWindowTitle('Dialog 01')
Button_01.clicked.connect(self.callAnotherQMainWindow)
def callAnotherQMainWindow(self):
self.hide()
self.dialog_02 = Dialog_02(self)
self.dialog_02.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
dialog_1 = Dialog_01()
dialog_1.show()
sys.exit(app.exec_())
In this code I'm not inheriting, but it works fine.
The issue is that when I try to follow the same syntax in the original question code, it won't run, I'm not sure I'm getting inheritances fine.
import sys
import os
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtWidgets import QPushButton, QVBoxLayout, QTextEdit, QHBoxLayout, QLabel, QMainWindow, QAction, QFileDialog
class SecondWindow(QWidget):
def __init__(self, Window):
super(SecondWindow, self).__init__(parent, QtCore.Qt.Window)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.text = QTextEdit(self)
self.btn_return= QPushButton("Return")
self.init_ui()
def init_ui(self):
v_layout = QVBoxLayout(self)
v_layout.addWidget(self.text)
v_layout.addWidget(self.btn_return)
self.setLayout(v_layout)
self.setWindowTitle('Opened Text')
self.btn_return.clicked.connect(self.closeAndReturn)
def closeAndReturn(self):
self.close()
self.parent().show()
class Window(QMainWindow):
textChanged = QtCore.pyqtSignal(str)
def __init__(self, *args):
super(Window, self).__init__()
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.img = QLabel()
self.load_file= QPushButton('Load')
self.width = 400
self.height = 150
self.init_ui()
def init_ui(self):
self.img.setPixmap(QtGui.QPixmap("someimage.png"))
h_layout = QHBoxLayout()
v_layout = QVBoxLayout()
h_final = QHBoxLayout()
h_layout.addWidget(self.img)
v_layout.addWidget(self.load_file)
h_final.addLayout(h_layout)
h_final.addLayout(v_layout)
self.load_file.clicked.connect(self.loadafile)
self.setLayout(h_final)
self.setWindowTitle('Main Window')
self.setGeometry(600,150,self.width,self.height)
#QtCore.pyqtSlot()
def loadafile(self):
filename = QFileDialog.getOpenFileName(self, 'Open File', os.getenv('HOME'))
with open(filename[0], 'r') as f:
file_text = f.read()
self.textChanged.emit(file_text)
self.hide()
self.dialog_02 = SecondWindow(self)
self.dialog_02.show()
def main():
app = QApplication(sys.argv)
main = Window()
s = SecondWindow(main)
main.textChanged.connect(s.text.append)
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
You are coupling many classes: What happens if at a moment SecondWindow does not have a parent? Well, your code will have problems and you will have to modify it a lot so that it works correctly. So first it is to design the behavior of each class, for example SecondWindow has to warn the other windows that it was clicked, it has to have a method that updates the text. Similarly, Window must notify that there is new text available.
On the other hand QMainWindow already has a predefined layout so you must create a centralwidget where you place the other widgets.
import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class SecondWindow(QtWidgets.QWidget):
closed = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(SecondWindow, self).__init__(parent, QtCore.Qt.Window)
self.text = QtWidgets.QTextEdit()
self.btn_return= QtWidgets.QPushButton("Return")
self.init_ui()
def init_ui(self):
v_layout = QtWidgets.QVBoxLayout(self)
v_layout.addWidget(self.text)
v_layout.addWidget(self.btn_return)
self.setWindowTitle('Opened Text')
self.btn_return.clicked.connect(self.close)
self.btn_return.clicked.connect(self.closed)
#QtCore.pyqtSlot(str)
def update_text(self, text):
self.text.setText(text)
self.show()
class Window(QtWidgets.QMainWindow):
textChanged = QtCore.pyqtSignal(str)
def __init__(self, *args):
super(Window, self).__init__()
self.img = QtWidgets.QLabel()
self.load_file= QtWidgets.QPushButton('Load')
self.width = 400
self.height = 150
self.init_ui()
def init_ui(self):
self.img.setPixmap(QtGui.QPixmap("someimage.png"))
self.load_file.clicked.connect(self.loadafile)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
h_layout = QtWidgets.QHBoxLayout(central_widget)
h_layout.addWidget(self.img)
h_layout.addWidget(self.load_file)
self.setWindowTitle('Main Window')
self.setGeometry(600,150,self.width,self.height)
#QtCore.pyqtSlot()
def loadafile(self):
filename, _ = QtWidgets.QFileDialog.getOpenFileName(self, 'Open File', os.getenv('HOME'))
if filename:
with open(filename, 'r') as f:
file_text = f.read()
self.textChanged.emit(file_text)
self.close()
def main():
app = QtWidgets.QApplication(sys.argv)
main = Window()
s = SecondWindow()
main.textChanged.connect(s.update_text)
s.closed.connect(main.show)
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Add different text to a window

I have a button and a text label. Each time the button is pressed, i would like text placed from a line edit to be placed onto the window. So far I can only get one text to draw onto the window, even if I create another textlabel. Ive tried seeting a click count determining how many times a user has clicked a button but this doesnt work either. Heres what I have so far, any suggestions?
import sys
import os
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtGui import QApplication
class Window(QMainWindow):
def __init__(self, *args):
QMainWindow.__init__(self, *args)
self.centralWidget = QWidget(self)
self.setCentralWidget(self.centralWidget)
self.setGeometry(450,100,350,680)
self.btn1 = QPushButton("Enter", self.centralWidget)
self.btn1.setGeometry(10,50,150, 20)
self.btn1.clicked.connect(self.enter)
self.edit = QtGui.QLineEdit(self)
self.edit.setGeometry(10, 10, 150, 20)
self.label = QtGui.QLabel(self)
self.label.setGeometry(240, 170,150, 20)
def enter(self):
self.label.setText(self.edit.text())
def main(args):
global app
app = App(args)
app.exec_()
class App(QApplication):
def __init__(self, *args):
QApplication.__init__(self, *args)
self.main = Window()
self.connect(self, SIGNAL("lastWindowClosed()"), self.byebye )
self.main.show()
def byebye( self ):
self.exit(0)
if __name__ == "__main__":
main(sys.argv)
There are a few problems with your example code, the main one being that you are trying to manually arrange the widgets, rather than using a layout.
It's hard to tell from your question exactly what you expect the output to be, so I've assumed you want the text from line-edit to be appended to the label, so that you end up with a series of lines.
Here's a simplified version of your example that hopefully does what you want:
from PyQt4 import QtCore, QtGui
class Window(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.btn1 = QtGui.QPushButton("Enter", self)
self.btn1.clicked.connect(self.enter)
self.edit = QtGui.QLineEdit(self)
self.label = QtGui.QLabel(self)
self.label.setAlignment(
QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)
widget = QtGui.QWidget(self)
layout = QtGui.QVBoxLayout(widget)
layout.addWidget(self.edit)
layout.addWidget(self.btn1)
layout.addWidget(self.label)
self.setCentralWidget(widget)
def enter(self):
text = self.edit.text()
if text:
self.label.setText('%s\n%s' % (self.label.text(), text))
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(450, 100, 350, 680)
window.show()
sys.exit(app.exec_())

Categories

Resources