Actual Code(posted on stack overflow) is pasted underneath . What i am trying is to remove the Start button and control status of the progressbar from a function inside some other class .
import sys, time
from PyQt4 import QtGui, QtCore
class ProgressBar(QtGui.QWidget):
def __init__(self, parent=None, total=20):
super(ProgressBar, self).__init__(parent)
self.progressbar = QtGui.QProgressBar()
self.progressbar.setMinimum(1)
self.progressbar.setMaximum(total)
self.button = QtGui.QPushButton('Start')
self.button.clicked.connect(self.handleButton)
main_layout = QtGui.QGridLayout()
main_layout.addWidget(self.button, 0, 0)
main_layout.addWidget(self.progressbar, 0, 1)
self.setLayout(main_layout)
self.setWindowTitle('Progress')
self._active = False
def handleButton(self):
if not self._active:
self._active = True
self.button.setText('Stop')
if self.progressbar.value() == self.progressbar.maximum():
self.progressbar.reset()
QtCore.QTimer.singleShot(0, self.startLoop)
else:
self._active = False
def closeEvent(self, event):
self._active = False
def startLoop(self):
while True:
time.sleep(0.05)
value = self.progressbar.value() + 1
self.progressbar.setValue(value)
QtGui.qApp.processEvents()
if (not self._active or
value >= self.progressbar.maximum()):
break
self.close()
app = QtGui.QApplication(sys.argv)
bar = ProgressBar(total=101)
bar.show()
sys.exit(app.exec_())
So i created a new class and replaced last few lines :
class drive():
app = QtGui.QApplication(sys.argv)
bar = ProgressBar(total=101)
bar.show()
sys.exit(app.exec_())
def control_progressbar(..):
...
a=drive()
Through function control_progressbar i want to modify the progressbar.
Related
I have a Qt widget that looks like this:
class launchiiwidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
layout = QtWidgets.QVBoxLayout(self)
self.textbox = QtWidgets.QTextEdit(self)
self.textbox.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
self.textbox.setAlignment(QtCore.Qt.AlignCenter)
self.textbox.setFixedSize(QtCore.QSize(600, 100))
self.textbox.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.textbox.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
layout.addWidget(self.textbox)
font = self.textbox.font()
font.setPointSize(80)
self.textbox.setFont(font)
self.listwidget = QtWidgets.QListWidget(self)
self.listwidget.addItem("Red")
self.listwidget.addItem("Blue")
layout.addWidget(self.listwidget)
if __name__ == "__main__":
app = QtWidgets.QApplication([])
widget = launchiiwidget()
widget.setWindowFlags(QtCore.Qt.FramelessWindowHint)
widget.resize(600, 200)
widget.show()
sys.exit(app.exec())
How can I make it so when the "return" or "right arrow key" is pressed, focus moves from wherever it is currently to the first item in listwidget? This should also work while being focused inside of textbox, without triggering a newline.
Note: items get dynamically added to listwidget.
A possible solution could be to use QShorcut but because the OP requires "without triggering a newline". So in this case the solution is to implement an eventfilter to the QWindow:
import sys
from PyQt6 import QtCore, QtGui, QtWidgets
class KeyHelper(QtCore.QObject):
pressed = QtCore.pyqtSignal()
def __init__(self, window):
super().__init__(window)
self._window = window
self.window.installEventFilter(self)
#property
def window(self):
return self._window
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.Type.KeyPress:
if event.key() in (
QtCore.Qt.Key.Key_Return,
QtCore.Qt.Key.Key_Enter,
QtCore.Qt.Key.Key_Right,
):
self.pressed.emit()
return True
return super().eventFilter(obj, event)
class Launchiiwidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.textbox = QtWidgets.QTextEdit()
self.textbox.setLineWrapMode(QtWidgets.QTextEdit.LineWrapMode.NoWrap)
self.textbox.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.textbox.setFixedSize(QtCore.QSize(600, 100))
self.textbox.setVerticalScrollBarPolicy(
QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff
)
self.textbox.setHorizontalScrollBarPolicy(
QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff
)
font = self.textbox.font()
font.setPointSize(80)
self.textbox.setFont(font)
self.listwidget = QtWidgets.QListWidget()
self.listwidget.addItem("Red")
self.listwidget.addItem("Blue")
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.textbox)
layout.addWidget(self.listwidget)
def update_focus(self):
self.listwidget.setFocus()
index = self.listwidget.model().index(0, 0)
if index.isValid():
self.listwidget.setCurrentIndex(index)
if __name__ == "__main__":
app = QtWidgets.QApplication([])
widget = Launchiiwidget()
widget.setWindowFlags(QtCore.Qt.WindowType.FramelessWindowHint)
widget.resize(600, 200)
widget.show()
key_helper = KeyHelper(widget.windowHandle())
key_helper.pressed.connect(widget.update_focus)
sys.exit(app.exec())
I write a program to that send and recive data from serial, but I have a problem, I want to create a function "connect()" or a class, and when I press a button, the function is executed, but if I create this function in "MainWindow" class, variable "ser" from "TestThread" class become uninitialized, can you help me?
import sys
import serial
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.uic import loadUi
ser = serial.Serial('/dev/tty.usbmodem14201', 9600, timeout=1)
class TestThread(QThread):
serialUpdate = pyqtSignal(str)
def run(self):
while ser.is_open:
QThread.sleep(1)
value = ser.readline().decode('ascii')
self.serialUpdate.emit(value)
ser.flush()
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
loadUi('/Users/bogdanvesa/P2A_GUI/mainwindow.ui', self)
self.thread = TestThread(self)
self.thread.serialUpdate.connect(self.handleSerialUpdate)
self.connect_btn.clicked.connect(self.connectSer)
self.lcd_EBtn.clicked.connect(self.startThread)
def startThread(self):
self.thread.start()
def handleSerialUpdate(self, value):
print(value)
self.lcd_lineEdit.setText(value)
def main():
app = QApplication(sys.argv)
form = MainWindow()
form.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Instead of using pySerial + thread it is better to use QSerialPort that is made to live with the Qt event-loop:
from PyQt5 import QtCore, QtWidgets, QtSerialPort
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.message_le = QtWidgets.QLineEdit()
self.send_btn = QtWidgets.QPushButton(
text="Send",
clicked=self.send
)
self.output_te = QtWidgets.QTextEdit(readOnly=True)
self.button = QtWidgets.QPushButton(
text="Connect",
checkable=True,
toggled=self.on_toggled
)
lay = QtWidgets.QVBoxLayout(self)
hlay = QtWidgets.QHBoxLayout()
hlay.addWidget(self.message_le)
hlay.addWidget(self.send_btn)
lay.addLayout(hlay)
lay.addWidget(self.output_te)
lay.addWidget(self.button)
self.serial = QtSerialPort.QSerialPort(
'/dev/tty.usbmodem14201',
baudRate=QtSerialPort.QSerialPort.Baud9600,
readyRead=self.receive
)
#QtCore.pyqtSlot()
def receive(self):
while self.serial.canReadLine():
text = self.serial.readLine().data().decode()
text = text.rstrip('\r\n')
self.output_te.append(text)
#QtCore.pyqtSlot()
def send(self):
self.serial.write(self.message_le.text().encode())
#QtCore.pyqtSlot(bool)
def on_toggled(self, checked):
self.button.setText("Disconnect" if checked else "Connect")
if checked:
if not self.serial.isOpen():
if not self.serial.open(QtCore.QIODevice.ReadWrite):
self.button.setChecked(False)
else:
self.serial.close()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
I have used the above code redesigned, so it has a mainwindow with a menubar and a statusbar. I also added the QSerialPortInfo class. This version will find active ports and display them on the status bar.
I only tested this on rpi 4 and Windows 10.
import sys
from PyQt5 import QtCore, QtWidgets, QtSerialPort
from PyQt5.QtWidgets import QApplication, QMainWindow ,QWidget ,QToolBar ,QHBoxLayout, QAction ,QStatusBar ,QLineEdit ,QPushButton ,QTextEdit , QVBoxLayout
from PyQt5.QtCore import Qt , pyqtSignal
from PyQt5.QtSerialPort import QSerialPortInfo
class AddComport(QMainWindow):
porttnavn = pyqtSignal(str)
def __init__(self, parent , menu):
super().__init__(parent)
menuComporte = menu.addMenu("Comporte")
info_list = QSerialPortInfo()
serial_list = info_list.availablePorts()
serial_ports = [port.portName() for port in serial_list]
if(len(serial_ports)> 0):
antalporte = len(serial_ports)
antal = 0
while antal < antalporte:
button_action = QAction(serial_ports[antal], self)
txt = serial_ports[antal]
portinfo = QSerialPortInfo(txt)
buttoninfotxt = " Ingen informationer"
if portinfo.hasProductIdentifier():
buttoninfotxt = ("Produkt specifikation = " + str(portinfo.vendorIdentifier()))
if portinfo.hasVendorIdentifier():
buttoninfotxt = buttoninfotxt + (" Fremstillers id = "+ str(portinfo.productIdentifier()))
button_action = QAction( txt , self)
button_action.setStatusTip( buttoninfotxt)
button_action.triggered.connect(lambda checked, txt = txt: self.valgAfComportClick(txt))
menuComporte.addAction(button_action)
antal = antal +1
else:
print("Ingen com porte fundet")
def valgAfComportClick(self , port):
self.porttnavn.emit(port)
def closeEvent(self, event):
self.close()
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
portname = "None"
self.setStatusBar(QStatusBar(self))
menu = self.menuBar()
comfinder = AddComport(self , menu)
comfinder.porttnavn.connect(self.valgAfComport)
self.setWindowTitle("Serial port display / send")
self.message_le = QLineEdit()
self.send_btn = QPushButton(
text="Send",
clicked=self.send
)
self.output_te = QTextEdit(readOnly=True)
self.button = QPushButton(
text="Connect",
checkable=True,
toggled=self.on_toggled
)
lay = QVBoxLayout(self)
hlay = QHBoxLayout()
hlay.addWidget(self.message_le)
hlay.addWidget(self.send_btn)
lay.addLayout(hlay)
lay.addWidget(self.output_te)
lay.addWidget(self.button)
widget = QWidget()
widget.setLayout(lay)
self.setCentralWidget(widget)
self.serial = QtSerialPort.QSerialPort(
portname,
baudRate=QtSerialPort.QSerialPort.Baud9600,
readyRead=self.receive)
#QtCore.pyqtSlot()
def receive(self):
while self.serial.canReadLine():
text = self.serial.readLine().data().decode()
text = text.rstrip('\r\n')
self.output_te.append(text)
#QtCore.pyqtSlot()
def send(self):
self.serial.write(self.message_le.text().encode())
#QtCore.pyqtSlot(bool)
def on_toggled(self, checked):
self.button.setText("Disconnect" if checked else "Connect")
if checked:
if not self.serial.isOpen():
self.serial.open(QtCore.QIODevice.ReadWrite)
if not self.serial.isOpen():
self.button.setChecked(False)
else:
self.button.setChecked(False)
else:
self.serial.close()
def valgAfComport(self , nyport):
seropen = False
if self.serial.isOpen():
seropen = True
self.serial.close()
self.serial.setPortName(nyport)
if seropen:
self.serial.open(QtCore.QIODevice.ReadWrite)
if not self.serial.isOpen():
self.button.setChecked(False)
print(nyport)
def closeEvent(self, event):
self.serial.close()
print("Comport lukket")
# print(comporttxt)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
I have a pyqt dialog that takes in a list of data that ends in a return (from a barcode scanner that has an auto return.)
The list is 5 items in length and currently I have to click "Add data" to run the populate_row method when 5 items are entered.
I split the string into a list using \n and deal with each item as needed.
Is there a way I can automate pressing the add data button when the number of lines or the number of \n reaches 5 in the QPlainTextEdit box?
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Status(QDialog):
def __init__(self, parent=None):
super(Status, self).__init__(parent)
self.label = QLabel()
self.btn = QPushButton("Input Data")
self.btn.clicked.connect(self.populate_row)
self.layout = QVBoxLayout()
self.layout.addWidget(self.btn)
self.layout.addWidget(self.label)
self.resize(660, 260)
self.setLayout(self.layout)
def populate_row(self, letter):
self.dialog = QDialog()
self.dialog.resize(660, 260)
self.textBox = QPlainTextEdit(self.dialog)
Rbtn = QPushButton("Add Data")
Rbtn.clicked.connect(
lambda: self.enter_data(self.textBox.toPlainText()))
layout = QVBoxLayout(self.dialog)
layout.addWidget(self.textBox)
layout.addWidget(Rbtn)
self.dialog.exec_()
def enter_data(self, text):
self.label.setText(text)
lst = text.split("\n")
try:
for x in lst:
if x != "":
print(x)
self.do_something_with_x()
except IndexError:
pass
self.update_data()
self.dialog.close()
def do_something_with_x(self):
print('Something done with x..')
def update_data(self):
print('Data updated..')
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Status()
ex.show()
sys.exit(app.exec_())
To count the line breaks use the blockCountChanged() signal, and if you want to click on the button you must use the click() method. Also to verify that a string is empty, it is enough with if x: since the strings are iterable and the if iterable returns False if it is empty, and True in other cases.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Status(QtWidgets.QDialog):
def __init__(self, parent=None):
super(Status, self).__init__(parent)
self.label = QtWidgets.QLabel()
self.btn = QtWidgets.QPushButton("Input Data")
self.btn.clicked.connect(self.populate_row)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.btn)
layout.addWidget(self.label)
self.resize(660, 260)
def populate_row(self, letter):
self.dialog = QtWidgets.QDialog()
self.dialog.resize(660, 260)
self.textBox = QtWidgets.QPlainTextEdit()
self.textBox.blockCountChanged.connect(self.blockCount)
self.Rbtn = QtWidgets.QPushButton("Add Data")
self.Rbtn.clicked.connect(self.runcode)
layout = QtWidgets.QVBoxLayout(self.dialog)
layout.addWidget(self.textBox)
layout.addWidget(self.Rbtn)
self.dialog.exec_()
#QtCore.pyqtSlot(int)
def blockCount(self, num):
if num > 5: self.Rbtn.click()
def runcode(self):
self.enter_data(self.textBox.toPlainText())
def enter_data(self, text):
self.label.setText(text)
for x in text.split("\n"):
if x:
print(x)
self.do_something_with_x()
self.update_data()
self.dialog.close()
def do_something_with_x(self):
print('Something done with x..')
def update_data(self):
print('Data updated..')
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = Status()
ex.show()
sys.exit(app.exec_())
void QPlainTextEdit::blockCountChanged(int newBlockCount)
This signal is emitted whenever the block count changes. The new block count is passed in newBlockCount.
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Status(QDialog):
def __init__(self, parent=None):
super(Status, self).__init__(parent)
self.label = QLabel()
self.btn = QPushButton("Input Data")
self.btn.clicked.connect(self.populate_row)
self.layout = QVBoxLayout()
self.layout.addWidget(self.btn)
self.layout.addWidget(self.label)
self.resize(660, 260)
self.setLayout(self.layout)
def populate_row(self, letter):
self.dialog = QDialog()
self.dialog.resize(660, 260)
self.textBox = QPlainTextEdit(self.dialog)
#
self.textBox.blockCountChanged[int].connect(self.blockCount) # +++
Rbtn = QPushButton("Add Data")
Rbtn.clicked.connect(
lambda: self.enter_data(self.textBox.toPlainText()))
layout = QVBoxLayout(self.dialog)
layout.addWidget(self.textBox)
#layout.addWidget(Rbtn) # ---
self.dialog.exec_()
## +++
def blockCount(self, num):
if num > 5:
self.enter_data(self.textBox.toPlainText())
##
def enter_data(self, text):
self.label.setText(text)
lst = text.split("\n")
try:
for x in lst:
if x != "":
print(x)
self.do_something_with_x()
except IndexError:
pass
self.update_data()
self.dialog.close()
def do_something_with_x(self):
print('Something done with x..')
def update_data(self):
print('Data updated..')
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Status()
ex.show()
sys.exit(app.exec_())
Hi I want to add the QProgressBar behind the QLIneEdit, just like it is in Safari Browser or IE, So here is my starting point how can I hook the ProgressBar and MyLineEdit together so that when user is done entering the path the progress bar should show the progress while the path is opened !!!
from PyQt4 import QtGui, QtCore
import sys
class ProgressBar(QtGui.QProgressBar):
""" docstring for ProgressBar
"""
def __init__(self, parent=None):
super(ProgressBar, self).__init__(parent)
self.timer = QtCore.QBasicTimer()
self.step = 0
self.doAction()
def timerEvent(self, e):
if self.step >= 100:
self.timer.stop()
return
self.step = self.step + 15
self.setValue(self.step)
def doAction(self):
if self.timer.isActive():
self.timer.stop()
else:
self.timer.start(100, self)
class MyLineEdit(QtGui.QLineEdit):
""" docstring for MyLineEdit
"""
def __init__(self, parent=None):
super(MyLineEdit, self).__init__(parent)
# I want to hook this bar at the backgroind of MyLineEdit
pbar = ProgressBar()
class Example(QtGui.QWidget):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
self.pbar = ProgressBar(self)
self.editbx = MyLineEdit(self.pbar)
newPalette = QtGui.QPalette()
newPalette.setColor(self.editbx.backgroundRole(), QtCore.Qt.transparent)
self.editbx.setPalette(newPalette)
self.editbx.setText("Defaukt text set")
self.editbx.setStyleSheet("QLineEdit { border:none;}")
self.pbar.setStyleSheet("QProgressBar {border:none;}")
self.initUI()
def initUI(self):
# self.pbar.setGeometry(30, 40, 200, 25)
self.setGeometry(300, 300, 280, 170)
self.setWindowTitle('QtGui.QProgressBar')
self.show()
def main():
app = QtGui.QApplication(sys.argv)
win = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I also looking forward to add a QCombobox in place of text entered so it can list the other existing folders, not the way QCompleter uses though becuase it doesnt has look of QCombobox, and I do not want to allow user to enter anything that doesnt exists.
Any help would be greatly appreciated.
I've attached an example of a QLineEdit with a progress bar behind it. It was heavily influenced by this post: http://www.qtcentre.org/threads/54758-Progress-bar-form-QLineEdit-issue
Basically you have to manage painting yourself. Unfortunately it didn't seem to work when I tried to do the same thing with a QComboBox. I would suggest posting a new question specifically about painting a progress bar on a QComboBox once you get up to it!
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class MyLineEdit(QLineEdit):
def __init__(self, parent=None):
QLineEdit.__init__(self, parent)
self.timer = QBasicTimer()
self.step = 0
self.doAction()
def timerEvent(self, e):
if self.step >= 100:
self.timer.stop()
return
self.step = self.step + 10
self.repaint()
def doAction(self):
if self.timer.isActive():
self.timer.stop()
else:
self.timer.start(1000, self)
def generateGradient(self, color):
gradient = QLinearGradient(0, 0, 0, self.height());
m_defaultBaseColor = self.palette().color(QPalette.Base)
gradient.setColorAt(0, m_defaultBaseColor)
gradient.setColorAt(0.15, color.lighter(120))
gradient.setColorAt(0.5, color)
gradient.setColorAt(0.85, color.lighter(120))
gradient.setColorAt(1, m_defaultBaseColor)
return gradient
def paintEvent(self, event):
p = QPainter(self)
panel = QStyleOptionFrameV2()
self.initStyleOption(panel)
self.style().drawPrimitive(QStyle.PE_PanelLineEdit, panel, p, self)
# an alternative to painting the QLineEdit is to do it only when the widget has focus and the progress bar is finished
#if self.hasFocus() or self.step >= 100: QLineEdit.paintEvent(self, event)
# however I've chosen to paint it always
QLineEdit.paintEvent(self, event)
painter = QPainter(self)
lenap = QStyleOptionFrameV2()
self.initStyleOption(lenap)
backgroundRect = self.style().subElementRect(QStyle.SE_LineEditContents, lenap, self)
# some alternative if statements you might like to use instead...
#
# if not self.hasFocus() and self.step < 100:
# if self.step < 100:
if True:
loadingColor = QColor(116,192,250)
painter.setBrush(self.generateGradient(loadingColor))
painter.setPen(Qt.transparent)
mid = int(backgroundRect.width()/100.0*self.step)
progressRect = QRect(backgroundRect.x(), backgroundRect.y(), mid, backgroundRect.height())
painter.drawRect(progressRect)
painter.setPen(Qt.SolidLine)
painter.drawText(backgroundRect, Qt.AlignLeft|Qt.AlignVCenter, " " + self.text())
class Window(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self._control = QWidget()
self.setCentralWidget(self._control)
l = QVBoxLayout(self._control)
e = MyLineEdit()
l.addWidget(e)
b = QPushButton('a')
l.addWidget(b)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Window()
sys.exit(app.exec_())
I have some trouble with creating window application using PyQt. For example: we have the following class for GUI:
class SampleMainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
...
def hideEvent(self, event):
...
def showEvent(self, event):
...
def activate(self):
...
def closeEvent(self, event):
...
What if we want to use it just for showing results and acept user inputs, and for all control logic we have another class, which use the instance of SampleMainWindow as a field:
class Programm:
def __init__(self):
self.window = SampleMainWindow()
....
app = QtGui.QApplication(sys.argv)
prog = Programm()
prog.window.show()
app.exec_()
So, if we create the instance of Programm, the application will run well, but on close we'll get an error that python.exe process could not be completed normally. But if the instance of SampleMainWindow is not a field of class:
class Programm:
def __init__(self):
win = SampleMainWindow()
....
application close well. What's the reason?
Here are the full version of Gui class:
class SampleMainWindow(QtGui.QMainWindow):
def initTray(self):
self.icon = QtGui.QSystemTrayIcon()
self.icon.setIcon(QtGui.QIcon('Tray.png'))
self.icon.show()
self.icon.activated.connect(self.activate)
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self)
moduleglobalconstants.APP_RUNNING = True
self.initTray()
self.newSession = True
self.setGeometry(300, 300, 600, 400)
self.setWindowTitle('Eye: Recently Added Lines')
self.statusBar().showMessage('Ready')
exitAction = QtGui.QAction(QtGui.QIcon('Exit.png')
,'Exit'
,self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit application')
self.connect(exitAction
,QtCore.SIGNAL('triggered()')
,QtCore.SLOT('close()'))
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAction)
self.toolbar = self.addToolBar('Exit')
self.toolbar.addAction(exitAction)
self.textEdit = QtGui.QTextEdit()
self.scrollPosition = self.textEdit.textCursor()
self.textEdit.setReadOnly(True)
self.setCentralWidget(self.textEdit)
def hideEvent(self, event):
self.hidden = True
self.setWindowFlags(QtCore.Qt.ToolTip)
self.setVisible(False)
def showEvent(self, event):
self.hidden = False
self.setVisible(True)
def activate(self):
self.setWindowFlags(QtCore.Qt.Window)
self.show()
self.setWindowState(self.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)
self.activateWindow()
def questionDialog(self, caption = 'Message',text = "Are you sure?"):
self.activate()
msgBox = QtGui.QMessageBox(self)
msgBox.setWindowTitle("Eye")
msgBox.setText(caption);
msgBox.setInformativeText(text);
msgBox.setStandardButtons(QtGui.QMessageBox.Yes| QtGui.QMessageBox.No);
msgBox.setDefaultButton(QtGui.QMessageBox.Yes);
return msgBox.exec_()
def criticalDialog(self,app, caption = 'Eye: Critical Error',text = "Impossible to continue working!"):
self.activate()
msgBox = QtGui.QMessageBox.critical(self,caption,text)
moduleglobalconstants.APP_RUNNING = False
def closeEvent(self, event):
reply = self.questionDialog()
if reply == QtGui.QMessageBox.Yes:
moduleglobalconstants.APP_RUNNING = False
event.accept()
else:
event.ignore()
def showNewLines(self, singleLine = None, lines = None, mode='insert'):
if (mode == 'rewrite'):
self.textEdit.clear()
if lines:
for line in lines:
self.textEdit.insertPlainText(line.strip() + "\n")
elif singleLine:
self.textEdit.insertPlainText(singleLine.strip()+"\n")
This has to do with python's garbage collecting - as (almost) soon an object isn't referenced anymore it destroys it, so I guess the process doesn't terminate as long as the window wasn't garbage-collected.
You can try to add at the end del Programm.window or something like that (there's probably a better way of doing this, but I never programmed QT myself so I can't help you here)
see this:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class MyWindow(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.label = QLabel("Hi, I'm a window", self)
self.button = QPushButton("&Quit", self)
self.connect(self.button, SIGNAL("clicked()"), QCoreApplication.instance(), SLOT("quit()"))
lay = QVBoxLayout()
lay.addWidget(self.label)
lay.addWidget(self.button)
self.setLayout(lay)
def closeEvent(self, event):
print "Closing the app"
self.deleteLater()
if __name__ == '__main__':
app = QApplication(sys.argv)
mw = MyWindow()
mw.show()
sys.exit(app.exec_())
the solution is to implement closeEvent method