Need help in connecting Connections in a class - python

I have created a window with QTableWidget having a cell with 2 buttons.
Buttons are created in seperate class where i am passing QTableWidget instance from main procedure.
I am not able to get the button events, which are connected in button Creation class. My code snippet is as below
class Buttons():
def __init__(self,tab):
buttonLayout = QtGui.QHBoxLayout()
buttonLayout.setContentsMargins(0,0,0,0)
self.saveButtonItem = QtGui.QPushButton('Save')
self.deleteButtonItem = QtGui.QPushButton('Delete')
buttonLayout.addWidget(self.saveButtonItem)
buttonLayout.addWidget(self.deleteButtonItem)
cellWidget = QtGui.QWidget()
cellWidget.setLayout(buttonLayout)
tab.insertRow(tab.rowCount())
tab.setCellWidget(tab.rowCount() - 1,0,cellWidget)
self.setconncection()
def setconncection(self):
self.saveButtonItem.clicked.connect(self.btnSaveClicked)
self.deleteButtonItem.clicked.connect(self.btnDeleteClicked)
print 'connections are set'
def btnSaveClicked(self):
print 'save clicked'
def btnDeleteClicked(self):
print 'delete clicked'
class testing(QtGui.QTableWidget):
def __init__(self):
super(testing,self).__init__()
self.setColumnCount(1)
for i in xrange(3):
self.r = Buttons(self)
if __name__ == "__main__" :
import sys
app = QtGui.QApplication (sys.argv)
win = testing ()
win.show()
sys.exit(app.exec_())
My window at run time is as below

After the __init__ of testing, the reference to Buttons instance is lost and the object is destroyed. (Variable r is affected but not used.)
Keeping a link to it (see last line in following code snippet) makes it work.
class testing(QtGui.QTableWidget):
def __init__(self):
super(testing,self).__init__()
self.setColumnCount(1)
self.setRowCount(1)
self.buttons = []
for i in xrange(3):
self.buttons.append(Buttons(self))

Related

PyQT5 Multi Thread Issue

I am trying to run Multithread using PYQT5 & Qthread
I have two pushbutton associated to threads (progressbar & one action waiting for 1 sec and then print "done") that are working perfectly as they are declared within the same Class.
I do have a third PushButton that I link to an action inserted within another Class. This one makes my program crash wihtout any log message. What exactly makes the program crash is the line "self.thread2.start()".
I do not understand why this is not working! can you help me undertsand the issue?
Thanks in advance
import sys
from PyQt5.QtCore import *
from thread_progressbar import *
from Test_MT import *
class SimulationUi(QtWidgets.QDialog):
def __init__(self):
super(SimulationUi, self).__init__()
self.btnStart = QtWidgets.QPushButton('Start')
self.btnStart2 = QtWidgets.QPushButton('Start')
self.btnStop = QtWidgets.QPushButton('Stop')
self.btnStop2 = QtWidgets.QPushButton('Stop')
self.btnQuit = QtWidgets.QPushButton('Quit')
self.myprogressbar = QtWidgets.QProgressBar()
self.myprogressbar2 = QtWidgets.QProgressBar()
self.grid = QtWidgets.QGridLayout()
self.grid.setSpacing(10)
self.grid.addWidget(self.btnStart,1,0)
self.grid.addWidget(self.btnStop,1,1)
self.grid.addWidget(self.myprogressbar,2,0,1,3)
self.grid.addWidget(self.btnStart2, 3, 0)
self.grid.addWidget(self.btnStop2, 3, 1)
self.setLayout(self.grid)
# ------------------------
#MULTI-THREAD MANAGEMENT
#------------------------
self.thread = QThread()
self.thread.start()
self.worker = thread_progressbar()
self.worker.moveToThread(self.thread)
self.worker.setValue.connect(self.myprogressbar.setValue)
self.btnStart.clicked.connect(self.worker.startpgbar)
self.btnStop.clicked.connect(lambda: self.worker.stoppgbar())
class_tst = MakeList()
class_tst.define_thread(self.btnStart2)
self.thread3 = QThread()
self.thread3.start()
self.worker3 = Test()
self.worker3.moveToThread( self.thread3 )
self.btnStop2.clicked.connect( self.worker3.MT )
def stop_thread(self):
self.worker.stop()
self.thread.quit()
self.thread.wait()
def quit_application(self):
self.close()
class MakeList():
def __init__(self):
super(MakeList, self).__init__()
def define_thread(self, MyObject):
self.thread2 = QThread()
self.thread2.start()
self.worker2 = Test()
self.worker2.moveToThread(self.thread2 )
MyObject.clicked.connect( self.worker2.MT )
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
simul = SimulationUi()
simul.show()
sys.exit(app.exec_())
Test_MT file
import os, time
from PyQt5 import QtCore
class Test(QtCore.QObject):
def MT(self):
time.sleep(1)
print("done")
Since the only reference to the MakeList instance in SimulationUi.__init__, is the local variable class_tst, this object together with it's attributes will be garbage collected when SimulationUi.__init__ returns. Since one of its attributes is a running thread (class_tst.thread2), this causes the program to crash. Easiest way around this is to make a persistent reference the MakeList object by assigning it to an instance variable of SimulationUi rather than to a local variable (i.e. use self.class_tst = MakeList() instead of class_tst=MakeList() in SimulationUi.__init__).

Can't invoke button click function() outside pyQT based GUI

I am trying to enhance the existing pyQT based GUI framework. The GUI is a multithread GUI based out of pyQT. I have taken some portion of it here to explain the problem
GUI.py - main python script that invokes function to create Tab on GUI
from TabWidgetClass import ConstructGUITabs
class mainWindow(QtGui.QMainWindow):
def __init__(self,**kwargs):
super().__init__()
self.dockList = []
#Lets build&run GUI
self.BuildRunGUI() ### initialize GUI
def BuildRunGUI(self):
### frame, status definition
### tab definition
self.mainWidget = QtGui.QTabWidget(self)
self.setCentralWidget(self.mainWidget)
self.GUIConnect = ConstructGUITabs(docklist=self.dockList, parent_widget=self.mainWidget,mutex=self.mutex)
self.show()
if __name__ == "__main__":
try:
mW = mainWindow()
mW.setGeometry(20, 30, 1920*0.9,1080*0.9)
mW.setTabPosition(QtCore.Qt.AllDockWidgetAreas, QtGui.QTabWidget.North)
#mW.show()
TabWidgetClass.py - Script to create tabs & widgets
from SerialInterface import SerialInterface
from BackQThread import BackQThread
class ConstructGUITabs():
def __init__():
super().__init__() #init!!
#Thread Variables
self.main_thread = None
self.background_thread = None
# Let's define each tab here
self.ADD_CALIBRATE_TAB()
############## Start of ADD_CONNECT_TAB##################################################
def ADD_CALIBRATE_TAB(self, tec_layout):
#Create threads here. Main to handle update in GUI & Background thread for few specific
#time consuming operation
self.main_thread = SerialInterface()
self.background_thread = BackQThread()
#Get button connect to get_value through main thread
self.get_button = QtGui.QLabel(self)
self.set_button = QtGui.QPushButton('Set')
self.set_button.clicked.connect(self.set_value)
#Set button connect to Set_value through background_thread
self.get_button = QtGui.QLabel(self)
self.get_button = QtGui.QPushButton('Get')
self.get_button.clicked.connect(self.get_new_value)
self.pwr_disp_val = QtGui.QLineEdit(self)
self.pwr_disp_val.setText('')
#add the layout
#connect signal for backgrund thread
self.background_thread.read_info_flash.connect(self.update_info_from_flash)
def set_value(self):
self.main_thread.setvalue()
def get_new_value(self):
self.background_thread.call_update_info_bg_thread(flag = 'ReadSignalInfo',
list=[var1, var2])
def update_info_from_flash(self,flashData):
self.pwr_disp_val.setText(flashData)
The 2 library modules SerialInterface & BackQThread are as below:
SerialInterface.py
import pyftdi.serialext
class LaserSerialInterface(object):
def __init__():
self.port = pyftdi.serialext.serial_for_url('COM1',
baudrate=9600,
timeout=120,
bytesize=8,
stopbits=1,
parity='N',
xonxoff=False,
rtscts=False)
def setValue(self, value):
self.port.write(value)
def readvalue(self,value):#nITLA
return (value * 100)
BackQThread.py
from SerialInterface import SerialInterface
class BackQThread(QtCore.QThread):
signal = QtCore.pyqtSignal(object)
read_info_flash = QtCore.pyqtSignal(object)
def __init__(self):
self.serial = SerialInterface()
def call_update_info_bg_thread(self,flag,**kwargs): #nITLA
self.flag = flag
self.kwargs = kwargs
def update_info_bg_thread(self, Signallist): #nITLA
flashData = []
for index in range(0, len(Singnallist)):
flashData.append(self.serial.readvalue(Signallist[index]))
self.read_info_flash.emit(flashData)
def run(self):
while True:
time.sleep(0.1)
if self.flag == None:
pass
elif self.flag == 'ReadSignalInfo':
self.update_info_bg_thread(Signallist = self.kwargs['Signallist'])
self.flag = False
All above interface works without issues.
The new requirement is to do automation on GUI. In such way that, execute GUI options without manually doing clicks. Script should get an access to ConstructGUITabs() class, to invoke the click events.
Here is sample test script which works fine, if I invoke click events.
GUI.py - script is modified to declare GUIConnect as global variables using 'import globfile'
from TabWidgetClass import ConstructGUITabs
import globfile
class mainWindow(QtGui.QMainWindow):
def __init__(self,**kwargs):
super().__init__()
self.dockList = []
#Lets build&run GUI
self.BuildRunGUI() ### initialize GUI
def BuildRunGUI(self):
### frame, status definition
### tab definition
self.mainWidget = QtGui.QTabWidget(self)
self.setCentralWidget(self.mainWidget)
globfile.GUIConnect = ConstructGUITabs(docklist=self.dockList, parent_widget=self.mainWidget,mutex=self.mutex)
........
Test_Script.py
import globfile
globfile.GUIConnect.get_button.click() #this invokes get_new_value
globfile.GUIConnect.set_button.click()# this set_value
As you see here, through *click() function we are again doing mouse click events. I dont want to do this.
So i tried
globfile.GUIConnect.set_value()# this set_value
# This set_Value() would work as we are using only single & main thread
globfile.GUIConnect.get_new_value() #this invokes get_new_value
# This function call wont' get completed. It would stuck at 'self.read_info_flash.emit(flashData)' in BackQThread.py script. Hence, background thread fails to run update function 'update_info_from_flash'.
Can anyone tell me, what is the wrong in invoking directly functions rather than click() events. Why multithread alone fails to complete.

PyQt5 dynamic creation/destruction of widgets

I have an application where upon start up the user is presented with a dialog to chose number of 'objects' required. This then generates necessary objects in the main window using a for loop (i.e. object1, object2, etc.). I want to move this selection into the main window so that this can be changed without the need to restart the application. I have no idea how to approach this as I'm not sure how to dynamically create/destroy once the application is running. Here's an example code that generates tabs in a tab widget with some elements in each tab.
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class SelectionWindow(QDialog):
def __init__(self):
QDialog.__init__(self)
self.settings = QSettings('Example', 'Example')
self.numberOfTabs = QSpinBox(value = self.settings.value('numberOfTabs', type=int, defaultValue = 3), minimum = 1)
self.layout = QFormLayout(self)
self.button = QPushButton(text = 'OK', clicked = self.buttonClicked)
self.layout.addRow('Select number of tabs', self.numberOfTabs)
self.layout.addRow(self.button)
def buttonClicked(self):
self.settings.setValue('numberOfTabs', self.numberOfTabs.value())
self.accept()
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.settings = QSettings('Example', 'Example')
self.tabs = self.settings.value('numberOfTabs', type = int)
self.tabWidget = QTabWidget()
for i in range(1, self.tabs + 1):
exec(('self.tab{0} = QWidget()').format(i))
exec(("self.tabWidget.addTab(self.tab{0}, 'Tab{0}')").format(i))
exec(('self.lineEdit{0} = QLineEdit()').format(i))
exec(('self.spinBox{0} = QSpinBox()').format(i))
exec(('self.checkBox{0} = QCheckBox()').format(i))
exec(('self.layout{0} = QFormLayout(self.tab{0})').format(i))
exec(("self.layout{0}.addRow('Name', self.lineEdit{0})").format(i))
exec(("self.layout{0}.addRow('Value', self.spinBox{0})").format(i))
exec(("self.layout{0}.addRow('On/Off', self.checkBox{0})").format(i))
self.setCentralWidget(self.tabWidget)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
dialog = SelectionWindow()
dialog.show()
if dialog.exec_() == SelectionWindow.Accepted:
mainwindow = MainWindow()
mainwindow.show()
sys.exit(app.exec_())
First of all, you should never use exec for things like these. Besides the security issues of using exec, it also makes your code less readable (and then much harder to debug) and hard to interact with.
A better (and more "elegant") solution is to use a common function to create tabs and, most importantly, setattr.
Also, you shouldn't use QSettings in this way, as it is mostly intended for cross-session persistent data, not to initialize an interface. For that case, you should just override the exec() method of the dialog and initialize the main window with that value as an argument.
And, even if it was the case (but I suggest you to avoid the above approach anyway), remember that to make settings persistent, at least organizationName and applicationName must be set.
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.settings = QSettings('Example', 'Example')
# this value does not need to be a persistent instance attribute
tabCount = self.settings.value('numberOfTabs', type = int)
# create a main widget for the whole interface
central = QWidget()
mainLayout = QVBoxLayout(central)
tabCountSpin = QSpinBox(minimum=1)
mainLayout.addWidget(tabCountSpin)
tabCountSpin.setValue(tabCount)
tabCountSpin.valueChanged.connect(self.tabCountChanged)
self.tabWidget = QTabWidget()
mainLayout.addWidget(self.tabWidget)
for t in range(tabCount):
self.createTab(t)
self.setCentralWidget(central)
def createTab(self, t):
t += 1
tab = QWidget()
self.tabWidget.addTab(tab, 'Tab{}'.format(t))
layout = QFormLayout(tab)
# create all the widgets
lineEdit = QLineEdit()
spinBox = QSpinBox()
checkBox = QCheckBox()
# add them to the layout
layout.addRow('Name', lineEdit)
layout.addRow('Value', spinBox)
layout.addRow('On/Off', checkBox)
# keeping a "text" reference to the widget is useful, but not for
# everything, as tab can be accessed like this:
# tab = self.tabWidget.widget(index)
# and so its layout:
# tab.layout()
setattr(tab, 'lineEdit{}'.format(t), lineEdit)
setattr(tab, 'spinBox{}'.format(t), spinBox)
setattr(tab, 'checkBox{}'.format(t), checkBox)
def tabCountChanged(self, count):
if count == self.tabWidget.count():
return
elif count < self.tabWidget.count():
while self.tabWidget.count() > count:
# note that I'm not deleting the python reference to each object;
# you should use "del" for both the tab and its children
self.tabWidget.removeTab(count)
else:
for t in range(self.tabWidget.count(), count):
self.createTab(t)

Use one QPushButton with two QLineEdits, depending on last focus

I have a window, which has two QLineEdits in it. They are Line 1 and Line 2. I have a Backspace QPushButton which is to be pressed. I want some code which, when the backspace is pressed, will delete the text from the desired QLineEdit. This is to be done based on which one is focused at the time.
I understand that currently my code will backspace line1, however I want it to delete whichever line edit most recently had focus (i.e. if line1 was selected before backspace, it will get backspaced, if line 2 was the last in focus, then it will be backspaced).
I'm thinking it requires an if statement or 2, not sure though. How do I choose which line edit is deleted based on which one last had focus?
from PySide import QtGui, QtCore
from PySide.QtCore import*
from PySide.QtGui import*
class MainWindow(QtGui.QMainWindow): #The Main Window Class Maker
def __init__(self,):
QtGui.QMainWindow.__init__(self)
QtGui.QApplication.setStyle(('cleanlooks'))
mfont = QFont()
mfont.setFamily("BankGothic LT")
mfont.setPointSize(40)
mfont.setBold(True)
xfont = QFont()
xfont.setFamily("BankGothic LT")
xfont.setPointSize(40)
xfont.setLetterSpacing(QFont.AbsoluteSpacing, 15)
self.line1 = QLineEdit("Line 1", self)
self.line1.setFixedSize(460, 65)
self.line1.setFont(xfont)
self.line1.move(10,10)
self.line2 = QLineEdit("Line 2", self)
self.line2.setFixedSize(460, 65)
self.line2.setFont(xfont)
self.line2.move(10,200)
#BackSpace button
back = QPushButton("BackSpace", self)
back.move(100,100)
back.setFixedSize(300,75)
back.setFont(mfont)
back.clicked.connect(self.line1.backspace)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.setWindowTitle("BackSpace")
window.resize(480, 400)
window.setMaximumSize(480,400)
window.setMinimumSize(480,400)
window.show()
sys.exit(app.exec_())
You can accomplish this by utilizing the editingFinished signal and some manipulation of which line edit is connected to your backspace function.
I'll post then entire code block and then explain the changes I made below it.
class MainWindow(QtGui.QMainWindow):
def __init__(self,):
QtGui.QMainWindow.__init__(self)
QtGui.QApplication.setStyle(('cleanlooks'))
mfont = QFont()
mfont.setFamily("BankGothic LT")
mfont.setPointSize(40)
mfont.setBold(True)
xfont = QFont()
xfont.setFamily("BankGothic LT")
xfont.setPointSize(40)
xfont.setLetterSpacing(QFont.AbsoluteSpacing, 15)
self.line1 = QLineEdit("Line 1", self)
self.line1.setFixedSize(460, 65)
self.line1.setFont(xfont)
self.line1.move(10,10)
self.line2 = QLineEdit("Line 2", self)
self.line2.setFixedSize(460, 65)
self.line2.setFont(xfont)
self.line2.move(10,200)
self.recent_line = self.line2
self.previous_line = self.line1
#BackSpace button
self.back = QPushButton("BackSpace", self)
self.back.move(100,100)
self.back.setFixedSize(300,75)
self.back.setFont(mfont)
self.back.clicked.connect(self.recent_line.backspace)
self.line1.editingFinished.connect(self.last_lineedit)
self.line2.editingFinished.connect(self.last_lineedit)
def last_lineedit(self):
if isinstance(self.sender(), QLineEdit):
self.recent_line, self.previous_line = self.previous_line, self.recent_line
self.back.clicked.disconnect(self.previous_line.backspace)
self.back.clicked.connect(self.recent_line.backspace)
The first change that I've made is to include two new variables so that we can keep track of which QLineEdit was focused on last:
self.recent_line = self.line2
self.previous_line = self.line1
Next, I changed your back widget to be self.back, because we are going to need it outside of __init__
self.back = QPushButton("BackSpace", self)
self.back.move(100,100)
self.back.setFixedSize(300,75)
self.back.setFont(mfont)
self.back.clicked.connect(self.recent_line.backspace)
Then we are going to set up both line1 and line2 to the editingFinished signal.
This signal is emitted when the Return or Enter key is pressed or the line edit loses focus.
We'll be utilizing the "loses focus" part, because when the self.back button is pressed, the QLineEdit has lost focus.
Finally we get to the function that is going to keep track of which QLineEdit is connected to the backspace button at any given time.
def last_lineedit(self):
if isinstance(self.sender(), QLineEdit):
self.recent_line, self.previous_line = self.previous_line, self.recent_line
self.back.clicked.disconnect(self.previous_line.backspace)
self.back.clicked.connect(self.recent_line.backspace)
Within this function, we fist ensure that only one of the QLineEdits are sending the signal (just in case you connect something else to this signal that isn't a QLineEdit).
Next, we swap which QLineEdit was most recently focused on:
self.recent_line, self.previous_line = self.previous_line, self.recent_line
Then we disconnect from the previous line and connect to the new line. These last two lines are the magic that allows you to delete from both lines based on which had focus most recently. These lines are also why we changed to self.back, instead of leaving it at back. The locally scoped back wasn't accessible from the last_lineedit function.
It would be best if the backspace button didn't steal focus. That way, the caret will stay visible in the line-edit that has focus, and the user can easily see exactly what is happening. Doing it this way also makes the code much simpler:
back.setFocusPolicy(QtCore.Qt.NoFocus)
back.clicked.connect(self.handleBackspace)
def handleBackspace(self):
widget = QtGui.qApp.focusWidget()
if widget is self.line1 or widget is self.line2:
widget.backspace()
Ok guys, so I kept working on this in order to find a useful situation, where one would use this sort of functionality.
Say you were trying to create a login form for a touch screen, but you had no onscreen keyboard installed, you can 'create' one. This is what the intended use was for.
I've sort of tested this, and fixed any bugs I saw, but hey, feel free to use it. I noticed that heaps of examples existed for calculators, but no real examples existed for Keypad or Numberpad entry. Enjoy!
from PySide import QtGui, QtCore
from PySide.QtCore import*
from PySide.QtGui import*
class MainWindow(QtGui.QMainWindow): #The Main Window Class Maker
def __init__(self,):
QtGui.QMainWindow.__init__(self)
QtGui.QApplication.setStyle(('cleanlooks'))
U = QLabel("U:", self)
U.move(10,10)
P = QLabel("P:", self)
P.move(10,50)
self.line1 = QLineEdit("", self)
self.line1.move(20,10)
self.line1.setReadOnly(True)
self.line2 = QLineEdit("", self)
self.line2.move(20,50)
self.line2.setReadOnly(True)
self.line2.setEchoMode(QLineEdit.Password)
#PushButtons
back = QPushButton("<", self)
back.move(100,80)
back.setFocusPolicy(QtCore.Qt.NoFocus)
back.setFixedSize(20,20)
one = QPushButton('1', self)
one.move(10,80)
one.setFocusPolicy(QtCore.Qt.NoFocus)
one.setText("1")
one.setFixedSize(20,20)
two = QPushButton('2', self)
two.move(40,80)
two.setFocusPolicy(QtCore.Qt.NoFocus)
two.setFixedSize(20,20)
three = QPushButton('3', self)
three.move(70,80)
three.setFocusPolicy(QtCore.Qt.NoFocus)
three.setFixedSize(20,20)
four = QPushButton('4', self)
four.move(10,110)
four.setFocusPolicy(QtCore.Qt.NoFocus)
four.setFixedSize(20,20)
five = QPushButton('5', self)
five.move(40,110)
five.setFocusPolicy(QtCore.Qt.NoFocus)
five.setFixedSize(20,20)
six = QPushButton('6', self)
six.move(70,110)
six.setFocusPolicy(QtCore.Qt.NoFocus)
six.setFixedSize(20,20)
seven = QPushButton('7', self)
seven.move(10,140)
seven.setFocusPolicy(QtCore.Qt.NoFocus)
seven.setFixedSize(20,20)
eight = QPushButton('8', self)
eight.move(40,140)
eight.setFocusPolicy(QtCore.Qt.NoFocus)
eight.setFixedSize(20,20)
nine = QPushButton('9', self)
nine.move(70,140)
nine.setFocusPolicy(QtCore.Qt.NoFocus)
nine.setFixedSize(20,20)
zero = QPushButton('0', self)
zero.move(100,140)
zero.setFocusPolicy(QtCore.Qt.NoFocus)
zero.setFixedSize(20,20)
enter = QPushButton("E", self)
enter.move(100,110)
enter.setFixedSize(20,20)
enter.setFocusPolicy(QtCore.Qt.NoFocus)
#click Handles
def handleBackspace():
backh = QtGui.qApp.focusWidget()
if backh is self.line1 or backh is self.line2:
backh.backspace()
def handleZero():
zeroh = QtGui.qApp.focusWidget()
if zeroh is self.line1:
zeroh.setText((self.line1.text()+str('0')))
else:
zeroh.setText(self.line2.text()+str('0'))
def handleOne():
oneh = QtGui.qApp.focusWidget()
if oneh is self.line1:
oneh.setText(self.line1.text()+str('1'))
else:
oneh.setText(self.line2.text()+str('1'))
def handleTwo():
twoh = QtGui.qApp.focusWidget()
if twoh is self.line1:
twoh.setText(self.line1.text()+str('2'))
else:
twoh.setText(self.line2.text()+str('2'))
def handleThree():
threeh = QtGui.qApp.focusWidget()
if threeh is self.line1:
threeh.setText(self.line1.text()+str('3'))
else:
threeh.setText(self.line2.text()+str('3'))
def handleFour():
fourh = QtGui.qApp.focusWidget()
if fourh is self.line1:
fourh.setText(self.line1.text()+str('4'))
else:
fourh.setText(self.line2.text()+str('4'))
def handleFive():
fiveh = QtGui.qApp.focusWidget()
if fiveh is self.line1:
fiveh.setText(self.line1.text()+str('5'))
else:
fiveh.setText(self.line2.text()+str('5'))
def handleSix():
sixh = QtGui.qApp.focusWidget()
if sixh is self.line1:
sixh.setText(self.line1.text()+str('6'))
else:
sixh.setText(self.line2.text()+str('6'))
def handleSeven():
sevenh = QtGui.qApp.focusWidget()
if sevenh is self.line1:
sevenh.setText(self.line1.text()+str('7'))
else:
sevenh.setText(self.line2.text()+str('7'))
def handleEight():
eighth = QtGui.qApp.focusWidget()
if eighth is self.line1:
eighth.setText(self.line1.text()+str('8'))
else:
eighth.setText(self.line2.text()+str('8'))
def handleNine():
nineh = QtGui.qApp.focusWidget()
if nineh is self.line1:
nineh.setText(self.line1.text()+str('9'))
else:
nineh.setText(self.line2.text()+str('9'))
#Click Conditions
self.connect(enter, SIGNAL("clicked()"), self.close)
zero.clicked.connect(handleZero)
nine.clicked.connect(handleNine)
eight.clicked.connect(handleEight)
seven.clicked.connect(handleSeven)
six.clicked.connect(handleSix)
five.clicked.connect(handleFive)
four.clicked.connect(handleFour)
three.clicked.connect(handleThree)
two.clicked.connect(handleTwo)
one.clicked.connect(handleOne)
back.clicked.connect(handleBackspace)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.setWindowTitle("LoginWindow")
window.resize(130, 180)
window.setMaximumSize(130, 180)
window.setMinimumSize(130, 180)
window.show()
sys.exit(app.exec_())

PySide QWidget immediate update

In my application, I have a call to an external module which spawns some threads, does some stuff, then returns a value. I'm trying to get a QMessageBox to show before and a QLabel to update after this is complete, but I'm stumped. The code goes something like this (called from QObject.connect on a button):
def _process(self):
self._message_box.show()
for i in range(3):
rv = external_module_function_with_threads() // blocking function call
label = getattr(self, "label%d" % (i + 1))
label.setText(rv)
When I click the button and the function is called, the message box only shows after the loop completes. The labels only update after the loop completes as well. I tried calling label.repaint() in the loop, but all that seems to do is make the message box show up earlier (but with no text in it).
I know I'm not violating the "GUI operations from outside the main thread" rule (...right?), so is there a way to force an update?
For your message box use self._message_box.exec_(). From my understanding of your question, I think this will do what you want.
from PySide.QtCore import *
from PySide.QtGui import *
import sys
import time
class Main(QWidget):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
layout = QVBoxLayout(self)
button = QPushButton("Press me")
self.label = QLabel("Run #")
map(layout.addWidget, [button, self.label])
button.pressed.connect(self.buttonPressed)
self.messageBox = QMessageBox()
def buttonPressed(self):
self.messageBox.exec_()
Thread().run(self.label)
class Thread(QThread):
def run(self, label):
for x in range(5):
self.updateLabel(label)
app.processEvents()
time.sleep(.5)
def updateLabel(self, label):
try:
number = int(label.text().split(" ")[-1])
number += 1
except ValueError:
number = 0
label.setText("Run %i" % number)
app = QApplication([])
main = Main()
main.show()
sys.exit(app.exec_())

Categories

Resources