I'm wondering if there is a way make a button send a message to a lineEdit variable in PyQt4. Here is my code so far:
import sys
from PyQt4 import QtGui,QtCore
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
qanda = QtGui.QLineEdit()
one = QtGui.QPushButton('1',self)
two = QtGui.QPushButton('2',self)
three = QtGui.QPushButton('3',self)
four = QtGui.QPushButton('4',self)
five = QtGui.QPushButton('5',self)
six = QtGui.QPushButton('6',self)
seven = QtGui.QPushButton('7',self)
eight = QtGui.QPushButton('8',self)
nine = QtGui.QPushButton('9',self)
zero = QtGui.QPushButton('0',self)
dot = QtGui.QPushButton('.',self)
minus = QtGui.QPushButton('-',self)
plus = QtGui.QPushButton('+',self)
multiply = QtGui.QPushButton('x',self)
divide = QtGui.QPushButton('/',self)
equals = QtGui.QPushButton('=',self)
backspace = QtGui.QPushButton('Backspace',self)
xsquared = QtGui.QPushButton('x^2',self)
xcubed = QtGui.QPushButton('x^3',self)
clear = QtGui.QPushButton('C',self)
one.clicked.connect(self.buttonClicked)
two.clicked.connect(self.buttonClicked)
three.clicked.connect(self.buttonClicked)
four.clicked.connect(self.buttonClicked)
five.clicked.connect(self.buttonClicked)
six.clicked.connect(self.buttonClicked)
seven.clicked.connect(self.buttonClicked)
eight.clicked.connect(self.buttonClicked)
nine.clicked.connect(self.buttonClicked)
zero.clicked.connect(self.buttonClicked)
dot.clicked.connect(self.buttonClicked)
minus.clicked.connect(self.buttonClicked)
plus.clicked.connect(self.buttonClicked)
multiply.clicked.connect(self.buttonClicked)
divide.clicked.connect(self.buttonClicked)
equals.clicked.connect(self.buttonClicked)
backspace.clicked.connect(self.buttonClicked)
xsquared.clicked.connect(self.buttonClicked)
xcubed.clicked.connect(self.buttonClicked)
clear.clicked.connect(self.buttonClicked)
grid = QtGui.QGridLayout()
grid.setSpacing(5)
grid.addWidget(qanda,0,0,1,4)
grid.addWidget(one,4,0)
grid.addWidget(two,4,1)
grid.addWidget(three,4,2)
grid.addWidget(four,3,0)
grid.addWidget(five,3,1)
grid.addWidget(six,3,2)
grid.addWidget(seven,2,0)
grid.addWidget(eight,2,1)
grid.addWidget(nine,2,2)
grid.addWidget(zero,5,0)
grid.addWidget(dot,5,1)
grid.addWidget(minus,5,3)
grid.addWidget(plus,4,3)
grid.addWidget(multiply,2,3)
grid.addWidget(divide,3,3)
grid.addWidget(equals,5,2)
grid.addWidget(backspace,1,0)
grid.addWidget(xsquared,1,1)
grid.addWidget(xcubed,1,2)
grid.addWidget(clear,1,3)
self.setLayout(grid)
self.setGeometry(300, 300, 250, 200)
self.setWindowTitle('ldm;sasdklhsdghk dgh jkl;')
self.show()
def buttonClicked(self):
sender = self.sender()
print(sender.text())
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
My goal is when someone clicks a button, such as x^2, x^2 will be displayed on the empty space that is the variable qanda.
If you are wondering, this is a calculator.
You need to keep a reference to the line-edit so that you can access it later:
def initUI(self):
self.qanda = QtGui.QLineEdit(self)
...
grid.addWidget(self.qanda,0,0,1,4)
...
Now you can set the text of the line-edit, like so:
def buttonClicked(self):
sender = self.sender()
print(sender.text())
self.qanda.setText(sender.text())
Have you tried setText method?
http://pyqt.sourceforge.net/Docs/PyQt4/qlineedit.html#setText
Related
I am building a GUI for obtaining user inputs and then using them in some complex step later. I have a group of checkboxes from which the user has to choose at least one and also provide an 'alias' name for it in the QLineEdit right below the checkbox (default name is taken otherwise).
Currently, I have to first enter the alias name and then check the checkbox to register the entered name in the line edit to get the value entered by the user and connected checkbox name. This order is not normal.
Is there a way to get the Editline data and the connected checkbox name when 'Continue' is clicked?
Here is my code:
from PyQt4 import QtGui, QtCore
import sys
checkpoint_list = ['Amsterdam','Munich','Paris','Mumbai']
class MyGui(QtGui.QWidget):
def __init__(self):
super(MyGui, self).__init__()
self.initUI()
self.final_list = []
self.platform_list = {}
self.qem = None
def initUI(self):
lay_out = QtGui.QVBoxLayout(self)
# select the CPs
cp_lbl = QtGui.QLabel("Please select CP versions to compare:", self)
lay_out.addWidget(cp_lbl)
self.cb = []
self.platform_label = []
i = 0
for cp in checkpoint_list:
self.cb.append(QtGui.QCheckBox(cp, self))
self.platform_label.append(QtGui.QLineEdit(cp, self))
self.cb[i].stateChanged.connect(self.clickBoxStateChanged)
lay_out.addWidget(self.cb[i])
lay_out.addWidget(self.platform_label[i])
i += 1
lay_out.addStretch(10)
# Continue and cancel button
btn_cancel = QtGui.QPushButton('Cancel', self)
btn_continue = QtGui.QPushButton('Continue', self)
hbox = QtGui.QHBoxLayout()
hbox.addStretch()
hbox.addWidget(btn_continue)
hbox.addWidget(btn_cancel)
vbox = QtGui.QVBoxLayout()
vbox.addStretch()
lay_out.addLayout(hbox)
lay_out.addLayout(vbox)
self.setLayout(lay_out)
btn_cancel.clicked.connect(self.onclick_cancel)
btn_cancel.setToolTip('To <b>Cancel</b> with this process')
btn_continue.clicked.connect(self.onclick_Continue)
btn_continue.setToolTip('To <b>Continue</b> with the matching')
# Screen show
self.setGeometry(300, 300, 500, 400)
self.setWindowTitle('CP Selection Window')
self.show()
def clickBoxStateChanged(self, cb):
self.final_list = []
self.platform_list = {}
for i in range(len(self.cb)):
if self.cb[i].isChecked():
if self.cb[i] not in self.final_list:
self.final_list.append(str(self.cb[i].text()))
self.platform_list[str(self.cb[i].text())] = str(self.platform_label[i].text())
print self.final_list
print self.platform_list
elif self.cb[i].isChecked() == False:
if self.cb[i].text() in self.final_list:
self.final_list.remove(str(self.cb[i].text()))
del self.platform_list[str(self.cb[i].text())]
print self.final_list
print self.platform_list
def onclick_Continue(self):
try:
if len(self.final_list) == 0:
self.qem = QtGui.QErrorMessage(self)
self.qem.showMessage("Please select at least 1 checkpoint to continue...")
else:
self.close()
except:
print "No CP was selected..."
def onclick_cancel(self):
sys.exit()
if __name__ == "__main__":
# GUI code
app = QtGui.QApplication(sys.argv)
w = MyGui()
app.exec_()
The simplest solution is to create a method that analyzes the information and that returns a dictionary of the selected elements:
class MyGui(QtGui.QWidget):
def __init__(self):
super(MyGui, self).__init__()
self.initUI()
def initUI(self):
lay_out = QtGui.QVBoxLayout(self)
# select the CPs
cp_lbl = QtGui.QLabel("Please select CP versions to compare:")
lay_out.addWidget(cp_lbl)
self.cb = []
self.platform_label = []
for cp in checkpoint_list:
cb = QtGui.QCheckBox(cp)
le = QtGui.QLineEdit(cp)
lay_out.addWidget(cb)
lay_out.addWidget(le)
self.cb.append(cb)
self.platform_label.append(le)
lay_out.addStretch(10)
# Continue and cancel button
btn_cancel = QtGui.QPushButton("Cancel")
btn_continue = QtGui.QPushButton("Continue")
hbox = QtGui.QHBoxLayout()
hbox.addStretch()
hbox.addWidget(btn_continue)
hbox.addWidget(btn_cancel)
vbox = QtGui.QVBoxLayout()
vbox.addStretch()
lay_out.addLayout(hbox)
lay_out.addLayout(vbox)
btn_cancel.clicked.connect(self.onclick_cancel)
btn_cancel.setToolTip("To <b>Cancel</b> with this process")
btn_continue.clicked.connect(self.onclick_Continue)
btn_continue.setToolTip("To <b>Continue</b> with the matching")
# Screen show
self.setGeometry(300, 300, 500, 400)
self.setWindowTitle("CP Selection Window")
self.show()
def get_elements_selected(self):
values_selected = dict()
for cb, le in zip(self.cb, self.platform_label):
if cb.isChecked():
values_selected[cb.text()] = le.text()
return values_selected
def onclick_Continue(self):
values = self.get_elements_selected()
if values:
print(values)
self.close()
else:
qem = QtGui.QErrorMessage(self)
qem.showMessage("Please select at least 1 checkpoint to continue...")
qem.exec_()
def onclick_cancel(self):
sys.exit()
I have created a widget with QLineEdit and QLabel, I want to get input from QlineEdit and display it with QLabel. I have used Signal and Slot connection, I do not know what I do wrong, but it is not working correctly. I would like to get both values from QLineEdit and later show it.
Current window
what I want?
Code:
import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class WinDialog(QtWidgets.QDialog):
currenttextedited = QtCore.pyqtSignal(int)
def __init__(self, parent=None):
super(WinDialog, self).__init__(parent)
self.setGeometry(300,300,350,300)
self.setWindowTitle("Signal & Slot")
self.propertyWidget = PropertyWidget()
section_lay = QtWidgets.QHBoxLayout()
section_label = QtWidgets.QLabel("Name: ")
section_edit = QtWidgets.QLineEdit('')
length_lay = QtWidgets.QHBoxLayout()
length_label = QtWidgets.QLabel("Input a number: L = ")
self.length_edit = QtWidgets.QLineEdit('1000')
self.length_edit.setInputMask("999999")
self.length_edit.setFocus(True)
thick_lay = QtWidgets.QHBoxLayout()
thick_label = QtWidgets.QLabel("Input a text: T = ")
thick_edit = QtWidgets.QLineEdit('')
section_lay.addWidget(section_label)
section_lay.addWidget(section_edit)
length_lay.addWidget(length_label)
length_lay.addWidget(self.length_edit)
length_lay.addStretch()
thick_lay.addWidget(thick_label)
thick_lay.addWidget(thick_edit)
thick_lay.addStretch()
VB_lay = QtWidgets.QVBoxLayout()
VB_lay.addStretch()
VB_lay.addLayout(length_lay)
VB_lay.addLayout(thick_lay)
VB_lay.addStretch()
buttonBox = QtWidgets.QDialogButtonBox()
buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel
|QtWidgets.QDialogButtonBox.Ok)
buttonBox.accepted.connect(self.accept)
buttonBox.rejected.connect(self.reject)
grid = QtWidgets.QGridLayout(self)
grid.addLayout(section_lay, 0, 0, 1, 2)
grid.addLayout(VB_lay, 1, 0)
grid.addWidget(self.propertyWidget, 2, 0)
grid.addWidget(buttonBox, 3, 0, 1, 2)
self.length_edit.textEdited.connect(self.textchanged)
def textchanged(self, text):
print(text)
self.currenttextedited.emit(text)
class PropertyWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(PropertyWidget, self).__init__(parent)
HB_lay = QtWidgets.QHBoxLayout(self)
self.Displaylabel = QtWidgets.QLabel('')
HB_lay.addWidget(self.Displaylabel)
HB_lay.addStretch()
#QtCore.pyqtSlot(int)
def Display(self, text):
try:
L_Display = int(text)
T_Display = int(text)
fmt = "L = {}mm\nT = {}mm"
self.Displaylabel.setText(fmt.format(L_Display, T_Display))
except ValueError:
print("Error")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = WinDialog()
w.show()
sys.exit(app.exec_())
according to samples in the image you want to show different texts but you are converting the same number to whole: L_Display = int(text) and T_Display = int(text) so how do you expect to show 2 different texts?, obviously the function display needs 2 entries (2 different entries to self plus I have changed to lowercase since it is recommended that the functions have a lowercase name).
Now the logic is as follows: if any of the texts of length_edit or thick_edit changes then you must call display() passing the new texts. So the solution is to use a slot that connects to the textEdited signals of both QLineEdits and in it obtain the text and pass the texts.
Finally I see that you want the QLineEdits receive only numbers so one option is to use a QIntValidator so that only numbers are acceptable (another better option is to use QSpinBox instead of QLineEdit)
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class WinDialog(QtWidgets.QDialog):
def __init__(self, parent=None):
super(WinDialog, self).__init__(parent)
self.setGeometry(300,300,350,300)
self.setWindowTitle("Signal & Slot")
self.propertyWidget = PropertyWidget()
section_lay = QtWidgets.QHBoxLayout()
section_label = QtWidgets.QLabel("Name: ")
section_edit = QtWidgets.QLineEdit('')
length_lay = QtWidgets.QHBoxLayout()
length_label = QtWidgets.QLabel("Input a number: L = ")
self.length_edit = QtWidgets.QLineEdit()
self.length_edit.setFocus(True)
val_lenght = QtGui.QIntValidator(0, 100000, self.length_edit)
self.length_edit.setValidator(val_lenght)
thick_lay = QtWidgets.QHBoxLayout()
thick_label = QtWidgets.QLabel("Input a text: T = ")
self.thick_edit = QtWidgets.QLineEdit()
val_thick = QtGui.QIntValidator(0, 100000, self.thick_edit)
self.thick_edit.setValidator(val_thick)
section_lay.addWidget(section_label)
section_lay.addWidget(section_edit)
length_lay.addWidget(length_label)
length_lay.addWidget(self.length_edit)
length_lay.addStretch()
thick_lay.addWidget(thick_label)
thick_lay.addWidget(self.thick_edit)
thick_lay.addStretch()
VB_lay = QtWidgets.QVBoxLayout()
VB_lay.addStretch()
VB_lay.addLayout(length_lay)
VB_lay.addLayout(thick_lay)
VB_lay.addStretch()
buttonBox = QtWidgets.QDialogButtonBox()
buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel
| QtWidgets.QDialogButtonBox.Ok)
buttonBox.accepted.connect(self.accept)
buttonBox.rejected.connect(self.reject)
grid = QtWidgets.QGridLayout(self)
grid.addLayout(section_lay, 0, 0, 1, 2)
grid.addLayout(VB_lay, 1, 0)
grid.addWidget(self.propertyWidget, 2, 0)
grid.addWidget(buttonBox, 3, 0, 1, 2)
self.length_edit.textEdited.connect(self.onTextEdited)
self.thick_edit.textEdited.connect(self.onTextEdited)
def onTextEdited(self):
l = self.length_edit.text()
t = self.thick_edit.text()
self.propertyWidget.display(l, t)
class PropertyWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(PropertyWidget, self).__init__(parent)
HB_lay = QtWidgets.QHBoxLayout(self)
self.Displaylabel = QtWidgets.QLabel('')
HB_lay.addWidget(self.Displaylabel)
HB_lay.addStretch()
def display(self, l, t):
try:
L_Display = int(l)
T_Display = int(t)
fmt = "L = {}mm\nT = {}mm"
self.Displaylabel.setText(fmt.format(L_Display, T_Display))
except ValueError:
self.Displaylabel.clear()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = WinDialog()
w.show()
sys.exit(app.exec_())
I have a list which is generated based on user-input.
I am trying to display this list in a QMessageBox. But, I have no way of knowing the length of this list. The list could be long.
Thus, I need to add a scrollbar to the QMessageBox.
Interestingly, I looked everywhere, but I haven’t found any solutions for this.
Below is, what I hope to be a “Minimal, Complete and Verifiable Example”, of course without the user input; I just created a list as an example.
I appreciate any advice.
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class W(QWidget):
def __init__(self):
super().__init__()
self.initUi()
def initUi(self):
self.btn = QPushButton('Show Message', self)
self.btn.setGeometry(10, 10, 100, 100)
self.btn.clicked.connect(self.buttonClicked)
self.lst = list(range(2000))
self.show()
def buttonClicked(self):
result = QMessageBox(self)
result.setText('%s' % self.lst)
result.exec_()
if __name__ == "__main__":
app = QApplication(sys.argv)
gui = W()
sys.exit(app.exec_())
You can not add a scrollbar directly since the widget in charge of displaying the text is a QLabel. The solution is to add a QScrollArea. The size may be inadequate so a stylesheet has to be used to set minimum values.
class ScrollMessageBox(QMessageBox):
def __init__(self, l, *args, **kwargs):
QMessageBox.__init__(self, *args, **kwargs)
scroll = QScrollArea(self)
scroll.setWidgetResizable(True)
self.content = QWidget()
scroll.setWidget(self.content)
lay = QVBoxLayout(self.content)
for item in l:
lay.addWidget(QLabel(item, self))
self.layout().addWidget(scroll, 0, 0, 1, self.layout().columnCount())
self.setStyleSheet("QScrollArea{min-width:300 px; min-height: 400px}")
class W(QWidget):
def __init__(self):
super().__init__()
self.btn = QPushButton('Show Message', self)
self.btn.setGeometry(10, 10, 100, 100)
self.btn.clicked.connect(self.buttonClicked)
self.lst = [str(i) for i in range(2000)]
self.show()
def buttonClicked(self):
result = ScrollMessageBox(self.lst, None)
result.exec_()
if __name__ == "__main__":
app = QApplication(sys.argv)
gui = W()
sys.exit(app.exec_())
Output:
Here is another way to override the widgets behavior.
You can get references to the children of the widget by using 'children()'.
Then you can manipulate them like any other widget.
Here we add a QScrollArea and QLabel to the original widget's QGridLayout. We get the text from the original widget's label and copy it to our new label, finally we clear the text from the original label so it is not shown (because it is beside our new label).
Our new label is scrollable. We must set the minimum size of the scrollArea or it will be hard to read.
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class ScrollMessageBox(QMessageBox):
def __init__(self, *args, **kwargs):
QMessageBox.__init__(self, *args, **kwargs)
chldn = self.children()
scrll = QScrollArea(self)
scrll.setWidgetResizable(True)
grd = self.findChild(QGridLayout)
lbl = QLabel(chldn[1].text(), self)
lbl.setWordWrap(True)
scrll.setWidget(lbl)
scrll.setMinimumSize (400,200)
grd.addWidget(scrll,0,1)
chldn[1].setText('')
self.exec_()
class W(QWidget):
def __init__(self):
super(W,self).__init__()
self.btn = QPushButton('Show Message', self)
self.btn.setGeometry(10, 10, 100, 100)
self.btn.clicked.connect(self.buttonClicked)
self.message = ("""We have encountered an error.
The following information may be useful in troubleshooting:
1
2
3
4
5
6
7
8
9
10
Here is the bottom.
""")
self.show()
def buttonClicked(self):
result = ScrollMessageBox(QMessageBox.Critical,"Error!",self.message)
if __name__ == "__main__":
app = QApplication(sys.argv)
gui = W()
sys.exit(app.exec_())
I'm trying to have text from feedparser scroll across the screen from right to left. I'm using PyQt5, I'm not sure how to go about adding this feature.
What I want to display is below
import feedparser
sports = feedparser.parse('http://rssfeeds.usatoday.com/UsatodaycomSports-TopStories')
for e in sports['entries']:
news = (e.get('title', ''))
I'm looking for a continuous scrolling until all the news headlines are read and then the page is reloaded to get the most recent headlines or just reread whats already there. Thanks!
You can use QTimeLine to show a continously scrolling slice of the news in a label. I implemented it in a little gui to try, if other functions in the app are blocked while QTimeLine is running:
import feedparser
import sys
from PyQt5 import QtWidgets, QtCore
class MyWidget(QtWidgets.QWidget):
def __init__(self, parent = None):
QtWidgets.QWidget.__init__(self, parent)
self.setGeometry(200, 200, 800, 600)
self.textLabel = QtWidgets.QLabel('') # label showing some text
self.uButton = QtWidgets.QPushButton('upper Button')
self.lButton = QtWidgets.QPushButton('lower Button')
self.label = QtWidgets.QLabel('') # label showing the news
self.label.setAlignment(QtCore.Qt.AlignRight) # text starts on the right
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.textLabel)
self.layout.addWidget(self.uButton)
self.layout.addWidget(self.lButton)
self.layout.addWidget(self.label)
self.layout.setStretch(0, 3)
self.layout.setStretch(1, 3)
self.layout.setStretch(2, 3)
self.layout.setStretch(3, 1)
self.setLayout(self.layout)
self.timeLine = QtCore.QTimeLine()
self.timeLine.setCurveShape(QtCore.QTimeLine.LinearCurve) # linear Timeline
self.timeLine.frameChanged.connect(self.setText)
self.timeLine.finished.connect(self.nextNews)
self.signalMapper = QtCore.QSignalMapper(self)
self.signalMapper.mapped[str].connect(self.setTlText)
self.uButton.clicked.connect(self.signalMapper.map)
self.signalMapper.setMapping(self.uButton, self.uButton.text())
self.lButton.clicked.connect(self.signalMapper.map)
self.signalMapper.setMapping(self.lButton, self.lButton.text())
self.feed()
def feed(self):
fm = self.label.fontMetrics()
self.nl = int(self.label.width()/fm.averageCharWidth()) # shown stringlength
news = []
sports = feedparser.parse('http://rssfeeds.usatoday.com/UsatodaycomSports-TopStories')
for e in sports['entries']:
news.append(e.get('title', ''))
appendix = ' '*self.nl # add some spaces at the end
news.append(appendix)
delimiter = ' +++ ' # shown between the messages
self.news = delimiter.join(news)
newsLength = len(self.news) # number of letters in news = frameRange
lps = 4 # letters per second
dur = newsLength*1000/lps # duration until the whole string is shown in milliseconds
self.timeLine.setDuration(dur)
self.timeLine.setFrameRange(0, newsLength)
self.timeLine.start()
def setText(self, number_of_frame):
if number_of_frame < self.nl:
start = 0
else:
start = number_of_frame - self.nl
text = '{}'.format(self.news[start:number_of_frame])
self.label.setText(text)
def nextNews(self):
self.feed() # start again
def setTlText(self, text):
string = '{} pressed'.format(text)
self.textLabel.setText(string)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
widget = MyWidget()
widget.show()
sys.exit(app.exec_())
Add PySide2 version:
import feedparser
import sys
from PySide2 import QtWidgets, QtCore
class MyWidget(QtWidgets.QWidget):
def __init__(self, parent = None):
QtWidgets.QWidget.__init__(self, parent)
self.setGeometry(200, 200, 800, 600)
self.textLabel = QtWidgets.QLabel('') # label showing some text
self.uButton = QtWidgets.QPushButton('upper Button')
self.lButton = QtWidgets.QPushButton('lower Button')
self.label = QtWidgets.QLabel('') # label showing the news
self.label.setAlignment(QtCore.Qt.AlignRight) # text starts on the right
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.textLabel)
self.layout.addWidget(self.uButton)
self.layout.addWidget(self.lButton)
self.layout.addWidget(self.label)
self.layout.setStretch(0, 3)
self.layout.setStretch(1, 3)
self.layout.setStretch(2, 3)
self.layout.setStretch(3, 1)
self.setLayout(self.layout)
self.timeLine = QtCore.QTimeLine()
self.timeLine.setCurveShape(QtCore.QTimeLine.LinearCurve) # linear Timeline
self.timeLine.frameChanged.connect(self.setText)
self.timeLine.finished.connect(self.nextNews)
self.signalMapper = QtCore.QSignalMapper(self)
self.signalMapper.mapped[str].connect(self.setTlText)
self.uButton.clicked.connect(self.signalMapper.map)
self.signalMapper.setMapping(self.uButton, self.uButton.text())
self.lButton.clicked.connect(self.signalMapper.map)
self.signalMapper.setMapping(self.lButton, self.lButton.text())
self.feed()
def feed(self):
fm = self.label.fontMetrics()
self.nl = int(self.label.width()/fm.averageCharWidth()) # shown stringlength
news = []
sports = feedparser.parse('http://rssfeeds.usatoday.com/UsatodaycomSports-TopStories')
for e in sports['entries']:
news.append(e.get('title', ''))
appendix = ' '*self.nl # add some spaces at the end
news.append(appendix)
delimiter = ' +++ ' # shown between the messages
self.news = delimiter.join(news)
newsLength = len(self.news) # number of letters in news = frameRange
lps = 4 # letters per second
dur = newsLength*1000/lps # duration until the whole string is shown in milliseconds
self.timeLine.setDuration(dur)
self.timeLine.setFrameRange(0, newsLength)
self.timeLine.start()
def setText(self, number_of_frame):
if number_of_frame < self.nl:
start = 0
else:
start = number_of_frame - self.nl
text = '{}'.format(self.news[start:number_of_frame])
self.label.setText(text)
def nextNews(self):
self.feed() # start again
def setTlText(self, text):
string = '{} pressed'.format(text)
self.textLabel.setText(string)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
widget = MyWidget()
widget.show()
sys.exit(app.exec_())
I am a beginner with GUI's and PYQT. What I am trying to do is dynamically set up a grid of QComboBox's and QLineEdit's. From the QComboBox you can select a choice and from that choice, it will fill in the corresponding QLineEdit with some numbers. The problem I'm having is creating the link between the first QComboBox and the first QLineEdit box. I could make a function for each row but I would like to know a better way. I will post some sample code. Thank you for any help or advice that you might have.
import sys
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class window(QMainWindow):
def __init__(self):
super(window, self).__init__()
self.setGeometry(50, 50, 700, 600)
self.home()
def home(self):
Test1Choices = ['Test1:','Choice1', 'Choice2', 'Choice3', 'Choice4','Choice5', 'Choice6', 'Choice7', 'Choice8', 'Choice9']
Test2Choices= ['Test2:','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']
for i in range(0,10):
Choice1ComboBox = QComboBox(self)
Choice1ComboBox.addItems(Test1Choices)
Choice1ComboBox.resize(150,25)
Choice1ComboBox.move(30,(150+(i*35)))
Choice1ComboBox.setCurrentIndex(2)
Choice2ComboBox = QComboBox(self)
Choice2ComboBox.setObjectName("Choice2ComboBox"+str(i))
Choice2ComboBox.addItems(Test2Choices)
Choice2ComboBox.resize(75,25)
Choice2ComboBox.move(200,(150+(i*35)))
Choice2ComboBox.setCurrentIndex(2)
Choice2ComboBox.activated[str].connect(self.doSomething)
numTextBox = QLineEdit(self)
numTextBox.setObjectName("numBox"+str(i))
numTextBox.move(325,(150+(i*35)))
numTextBox.resize(35,25)
result1TextBox = QLineEdit(self)
result1TextBox.setObjectName("result1Box"+str(i))
result1TextBox.move(400,(150+(i*35)))
result1TextBox.resize(100,25)
result1TextBox.setEnabled(0)
result2TextBox = QLineEdit(self)
result2TextBox.setObjectName("result2Box"+str(i))
result2TextBox.move(525,(150+(i*35)))
result2TextBox.resize(100,25)
result2TextBox.setEnabled(0)
self.show()
def doSomething(self):
numbers=['result1','result2','result3','result4','result5','result6','result7','result8','result9','result10','result11','result12','result13','result14','result15']
def run():
app = QApplication(sys.argv)
Gui = window()
sys.exit(app.exec_())
run()
To summarize I would like to bring in the index of the selected QComboBox. Then use that index number to reference the answer that is in the "numbers" array. Then print that result in the QLineEdit that is in the same row
We use sender() to get the object that emits the signal, then we look for the name of that object with setObjectName(), and we search the index, then we get the other objects with findChildren(), for example the output will be the union of the selected texts.
add name to Choice1ComboBox:
Choice1ComboBox.setObjectName("Choice1ComboBox"+str(i))
doSomething function:
def doSomething(self, _):
sender = self.sender()
l = sender.objectName().split("Choice1ComboBox")
if len(l) > 1:
number = l[1]
else:
number = sender.objectName().split("Choice2ComboBox")[1]
combo1 = self.findChildren(QComboBox, "Choice1ComboBox"+number)[0]
combo2 = self.findChildren(QComboBox, "Choice2ComboBox"+number)[0]
obj = self.findChildren(QLineEdit, "numBox"+number)[0]
obj.setText(combo1.currentText() + " " + combo2.currentText())
Complete code:
import sys
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class window(QMainWindow):
def __init__(self):
super(window, self).__init__()
self.setGeometry(50, 50, 700, 600)
self.home()
def home(self):
Test1Choices = ['Test1:','Choice1', 'Choice2', 'Choice3', 'Choice4','Choice5', 'Choice6', 'Choice7', 'Choice8', 'Choice9']
Test2Choices= ['Test2:','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']
for i in range(0,10):
Choice1ComboBox = QComboBox(self)
Choice1ComboBox.setObjectName("Choice1ComboBox"+str(i))
Choice1ComboBox.addItems(Test1Choices)
Choice1ComboBox.resize(150,25)
Choice1ComboBox.move(30,(150+(i*35)))
Choice1ComboBox.setCurrentIndex(2)
Choice1ComboBox.activated[str].connect(self.doSomething)
Choice2ComboBox = QComboBox(self)
Choice2ComboBox.setObjectName("Choice2ComboBox"+str(i))
Choice2ComboBox.addItems(Test2Choices)
Choice2ComboBox.resize(75,25)
Choice2ComboBox.move(200,(150+(i*35)))
Choice2ComboBox.setCurrentIndex(2)
Choice2ComboBox.activated[str].connect(self.doSomething)
numTextBox = QLineEdit(self)
numTextBox.setObjectName("numBox"+str(i))
numTextBox.move(325,(150+(i*35)))
numTextBox.resize(35,25)
result1TextBox = QLineEdit(self)
result1TextBox.setObjectName("result1Box"+str(i))
result1TextBox.move(400,(150+(i*35)))
result1TextBox.resize(100,25)
result1TextBox.setEnabled(0)
result2TextBox = QLineEdit(self)
result2TextBox.setObjectName("result2Box"+str(i))
result2TextBox.move(525,(150+(i*35)))
result2TextBox.resize(100,25)
result2TextBox.setEnabled(0)
self.show()
def doSomething(self, _):
sender = self.sender()
l = sender.objectName().split("Choice1ComboBox")
if len(l) > 1:
number = l[1]
else:
number = sender.objectName().split("Choice2ComboBox")[1]
combo1 = self.findChildren(QComboBox, "Choice1ComboBox"+number)[0]
combo2 = self.findChildren(QComboBox, "Choice2ComboBox"+number)[0]
obj = self.findChildren(QLineEdit, "numBox"+number)[0]
obj.setText(combo1.currentText() + " " + combo2.currentText())
def run():
app = QApplication(sys.argv)
Gui = window()
sys.exit(app.exec_())
run()