Displaying a function output directly to a QtextBrowser - python

im fairly new to coding even more at object oriented python so please bear with me.
Im trying to build a GUI for a program i coded before using PyQt5.
I've designed my forms at Qt Designer then used python -m PyQt5.uic.pyuic -x [FILENAME].ui -o [FILENAME].py to get the file as .py.
in order to avoid to change the file, im using another python file to call the form.py file and my program.py and build everything there
import sys
from myform import Ui_MainWindow
from mydialog1 import Ui_Dialog as Dlog_1
from mydialog2 import Ui_Dialog as Dlog_2
from PyQt5 import QtCore, QtGui, QtWidgets
from myprogram import *
class Prog(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super(Prog, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.show()
self.ui.actionAbout.triggered.connect(self.about)
self.ui.textBrowser.append(show())
def about(self):
dialog = QtWidgets.QDialog()
dialog.ui = Dlog_1()
dialog.ui.setupUi(dialog)
dialog.ui.Adicionar_3.clicked.connect(dialog.close)
dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
dialog.exec_()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = Prog()
MainWindow.show()
sys.exit(app.exec_())
Im trying to display the output from a function (from myprogram) to a QTextBrowser widget as it can be seen self.ui.textBrowser.append(show()) although this works with plain text for example ("test") it wont work with a function.
the function show() is defined as the following
def show():
global empresas
info = ["Nome da empresa", "Site da empresa", "Montante investido"]
valid = False
while not valid:
try:
gen = ((k, v[0], v[1]) for k, v in empresas.items())
ename, esite, evalue = zip(*gen)
valid = True
except ValueError:
print('Não existem empresas para mostrar. Introduza mais empresas')
return
print("")
a = ('|{}{:^30}{}| |{}{:^30}{}| |{}{:^30}{}|'.format(c['g'],info[0],c['d'],c['g'],info[1],c['d'],c['g'],info[2],c['d']))
print("+" + "=" * (len(a)-32) + "+")
print(a)
print("+" + "=" * (len(a)-32) + "+")
for y in range(0,len(ename)):
if y % 2 == 0:
print(f'|{ename[y]:^30}| |{esite[y]:^30}| |{evalue[y]:^17.3f}Milhões de',simb, '|')
print("+" + "-" * (len(a)-32) + "+")
elif y % 2 == 1:
print(f'|{ename[y]:^30}| |{esite[y]:^30}| |{evalue[y]:^17.3f}Milhões de',simb, '|')
print("+" + "-" * (len(a)-32) + "+")
return
This function basicly prints an organized table with all the items from a dictionary to the console.
Is there a way that allows me to print the same type of output to a QtextBrowser as it would look on the console?
Thanks in advance

If you really do not want to alter your show function to return a string instead of directly printing it, you could use stdout redirection for that. Basically this just tells print to write into your own buffer, which you can afterwards flush into the actual target that the string should go to:
from contextlib import redirect_stdout
import io
# in __init__ :
f = io.StringIO() # in-memory string buffer
with redirect_stdout(f):
# everything printed in here will go to f
show()
# now reroute everything written to f to textBrowser
self.ui.textBrowser.append(f.getvalue())

Related

Problem to reload a loop with Qdial, signal & subprocess

I am trying to record and use data with a Qdial.
For the recording every thing seems to be fine, but in order to use this data in while loop I have to reload the while loop. When I do so with signal and a subprocess, the loop seems to use every data recorded, another problem is that the loop don’t stop at the end of the process.
I have no doubt I am using the wrong method.
Sorry for my bad English, and thank you very much for your help.
So I am using 3 scripts: Qdial.py, Data.py, Loop.py.
The Data.py is an accumulation of data, here I use just one:
A1 = 10
The Loop.py is in deed my main script, here I resume:
import time
from Data import *
def loop():
while True:
print('A1 = ', A1)
time.sleep(0.1)
loop()
[edit] Instead of this Loop.py I will not use from Data import *,
but this one witch don't raise errors (but there is always the problem of the continuous looping after the exit on Qdial.py):
import time
def loop():
with open('/address/Data.py', 'r') as file:
lines = file.readlines()
A1 = lines[0]
A1 = float(A1[4:-1])
print('A1 = ', A1)
while True:
loop()
time.sleep(0.09)
[/edit]
The Qdial.py is a common one, with the signal and a subprocess that raise false values:
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import *
from Data import *
import sys, signal, subprocess, time
[edit] This line is no longer needed, and cause an endless loop.
I launch Loop.py with a subprocess:
proc = subprocess.Popen(['python3', '/address/Loop.py'])
[/edit]
Then it’s the writing for the Qdial:
class Window(QWidget):
def __init__(self):
super().__init__()
self.setGeometry(300, 300, 150, 150)
vbox = QVBoxLayout()
self.a1 = QDial(self)
self.value = int(A1)
self.a1.setValue(self.value)
self.value = self.a1.value()
self.lab1 = QtWidgets.QLabel(self)
self.lab1.setText('A1 = ' + str(A1) + 's')
self.a1.valueChanged.connect(self.dial)
vbox.addWidget(self.a1)
vbox.addWidget(self.lab1)
self.setLayout(vbox)
self.show()
def dial(self):
val1 = self.a1.value()
self.lab1.setText('A1 = ' + str(val1) + 's')
with open('/address/data.py', 'r') as file:
lines = file.readlines()
lines[0] = 'A1 = ' + str(val1) + '\n'
with open('/address/data.py', 'w') as file:
for line in lines:
file.write(line)
file.close()
[edit] Thoses lines are no longer define or needed.
Here I use signal and subprocess in order to reload the data in Loop.py:
proc.send_signal(signal.SIGINT)
subprocess.Popen(['python3', '/address/Loop.py'])
[/edit]
And I finish:
app = QApplication(sys.argv)
window = Window()
sys.exit(app.exec_())
[edit] A solution to escape the endless loop was to run both scripts (Qdial.py & Loop.py) as subprocess from a main script and use Popen.wait(), Main.py:
import subprocess, signal
Qd = subprocess.Popen(['python3', '/address/Qdial.py'])
Lo = subprocess.Popen(['python3', '/address/Loop.py'])
if Qd.wait() != None:
Lo.send_signal(signal.SIGINT)
[/edit]
Of course I don’t understand what is wrong, sorry for the length of this post...Thanks again.

New row in model doesn't persist in QDataWidgetMapper when QFileDialog is called

I have a simple form where I have a function/method which calls a QFileDialog to choose a file. This form stores the information in a Postgresql database and uses QDataWidgetMapper to map the form fields to database fields. When I add a new row to the model and edit some fields, when I call the QFileDialog, it seems the mappings get removed. All the edited fields on the form go blank. If I go back to a record which was retrieved from the database, I have no problems adding the image as the data persists on the form.
It seems to be related to the submit = self.c_mapper.submit() line of code. When I comment this out, the data persists in the form but I also can’t get the query().LastInsertId().
When stepping through the code, the form field data disappears when if dlg.exec_() == QDialog.Accepted: line is reached.
The desired behaviour is to be able to call the function which selects the image file and continue editing the same record with the correct data in the fields.
See the animation:
See the code:
import sys
import os
from pathlib import Path
import shutil
#PyQt stuff
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
from PyQt5.QtWidgets import *
#form modules
from form import *
class Contact(QMainWindow):
def __init__(self, cont_id, parent=None):
QMainWindow.__init__(self)
self.cont_id = cont_id
self.ui = Ui_contact_form()
self.ui.setupUi(self)
self.c_model = QSqlTableModel(self)
self.c_model.setTable("contacts")
self.c_model.select()
self.row = self.c_model.rowCount()
self.c_model.insertRow(self.row)
self.setWindowTitle('New contact')
self.c_mapper = QDataWidgetMapper(self)
self.c_mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit)
self.c_mapper.setModel(self.c_model)
#self.c_mapper.setItemDelegate(QSqlRelationalDelegate(self))
self.c_mapper.addMapping(self.ui.title, self.c_model.fieldIndex("title"))
self.c_mapper.addMapping(self.ui.first_name, self.c_model.fieldIndex("first_name"))
self.c_mapper.addMapping(self.ui.last_name, self.c_model.fieldIndex("last_name"))
self.c_mapper.addMapping(self.ui.nickname, self.c_model.fieldIndex("nickname"))
self.c_mapper.addMapping(self.ui.job_title, self.c_model.fieldIndex("job_title"))
self.c_mapper.addMapping(self.ui.birth_date, self.c_model.fieldIndex("birth_date"))
self.c_mapper.addMapping(self.ui.website, self.c_model.fieldIndex("website"))
self.c_mapper.addMapping(self.ui.comments, self.c_model.fieldIndex("comments"))
self.c_mapper.addMapping(self.ui.users, self.c_model.fieldIndex("user_name"))
self.c_mapper.addMapping(self.ui.tags, self.c_model.fieldIndex("tags"))
self.c_mapper.setCurrentIndex(self.row)
self.ui.get_image_file.clicked.connect(self.get_profile_image)
def get_profile_image(self):
submit = self.c_mapper.submit()
self.cont_id = self.c_model.query().lastInsertId()
data_loc = Path('/home/dave/hd/Nextcloud/crm_data/')
database = 'crm'
dlg = QFileDialog(self)
dlg.setFileMode(QFileDialog.AnyFile)
home = os.path.expanduser('~') + "/Downloads"
dlg.setDirectory(home)
if dlg.exec_() == QDialog.Accepted:
selected_file = dlg.selectedFiles()[0]
else:
return
selected_file = Path(selected_file)
ext = selected_file.suffix
ext = ext.lower()
target_loc = data_loc / database / "contacts/images"
target_file = str(self.cont_id) + ext
target_dest = target_loc / target_file
shutil.move(str(selected_file), str(target_dest))
self.ui.image.setPixmap(QPixmap(str(target_dest)).scaled(self.ui.image.size(),Qt.KeepAspectRatio))
if __name__=="__main__":
app=QApplication(sys.argv)
db = QSqlDatabase.addDatabase("QPSQL");
db.setHostName('hostname')
db.setDatabaseName('crm')
db.setUserName('usr')
db.setPassword('pw')
if (db.open()==False):
QMessageBox.critical(None, "Database Error", db.lastError().text())
myapp = Contact('')
myapp.show()
sys.exit(app.exec_())

PyQt 5 QTableWidget.cellClicked Signal Not Working

I am trying to make a simple files app (or, file explorer app) and I am using the QTableWidget to Display the files and directories. When the user clicks an directory, I want the program to jump to that directory. I have used the QTableWidget.cellClicked signal, and it does not currently work.
The signal part:
self.filesTable.connect(print)#self.updateUiCellClick)
Added print instead of self.updateUiCellClick for debugging purposes.
Code (probably you do not need this):
#!/usr/bin/python3
print('i Import Modules')
print(' | Import sys')
import sys
print(' | Import PyQt5.QtCore')
from PyQt5.QtCore import *
print(' | Import PyQt5.QtGui')
from PyQt5.QtGui import *
print(' | Import PyQt5.QtWidgets')
from PyQt5.QtWidgets import * # PyQt5 Support
print(' | Import os')
import os
print(' | Import subprocess.Popen') # For backward-compatibility
from subprocess import Popen, PIPE
print(' | Done')
print('i Define class Form')
class root(QMainWindow):
def __init__(self, parent=None):
'''self.__init__ - Initializes QMainWindow'''
print(' self.__init__ - Initializes QMainWindow')
super(root, self).__init__(parent)
# Create Variables
self.currentPath = '/'
os.chdir(self.currentPath)
self.currentItems = os.listdir()
self.currentItemsLsProcess = Popen(['ls','-l'], stdout=PIPE, stderr=PIPE)
self.currentItemsLsProcessResult = self.currentItemsLsProcess.communicate()
if self.currentItemsLsProcessResult[1].decode('utf-8'):
QMessageBox.warning(self,'Files - ls -l Error','ls -l responded with non-blank stderr.Error is shown here:<br><code>{}</code><br><hr><br>Error LsStderr (e-lsstderr)<br><hr><br>If you want to support the team, go to the GitHub Repository.'.format(self.currentItemsLsProcessResult[1].decode('utf-8')))
self.currentItemsLs = self.currentItemsLsProcessResult[0].decode('utf-8').split('\n')[1:-1]
# Create Table Widget
self.filesTable = QTableWidget()
# Init Table Widget
self.filesTable.clear()
self.filesTable.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
self.filesTable.setRowCount(len(self.currentItems))
self.filesTable.setColumnCount(4)
self.filesTable.setHorizontalHeaderLabels(['Name','TimeStamp','Type','ls -l'])
# self.filesTable.setReadOnly(1)
# Create & Add Items
self.itemWidgets = [[],[],[],[]]
for i in range(len(self.currentItems)):
self.itemWidgets[0].append(QTableWidgetItem(self.currentItems[i]))
self.filesTable.setItem(i,0,self.itemWidgets[0][-1])
self.itemWidgets[3].append(QTableWidgetItem(self.currentItemsLs[i]))
self.filesTable.setItem(i,3,self.itemWidgets[3][-1])
# Init Widgets
# Align Widgets to root
self.setCentralWidget(self.filesTable)
# Signals-and-Slots
print('i Set self title')
self.setWindowTitle('{}'.format(self.currentPath))
def updateUi(self):
'''self.updateUi - None'''
os.chdir(self.currentPath)
self.currentItems = os.listdir()
self.currentItemsLsProcess = Popen(['ls','-l'], stdout=PIPE, stderr=PIPE)
self.currentItemsLsProcessResult = self.currentItemsLsProcess.communicate()
if self.currentItemsLsProcessResult[1].decode('utf-8'):
QMessageBox.warning(self,'Files - ls -l Error','ls -l responded with non-blank stderr.Error is shown here:<br><code>{}</code><br><hr><br>Error LsStderr (e-lsstderr)<br><hr><br>If you want to support the team, go to the GitHub Repository.'.format(self.currentItemsLsProcessResult[1].decode('utf-8')))
self.currentItemsLs = self.currentItemsLsProcessResult[0].decode('utf-8').split('\n')[1:-1]
self.filesTable.clear()
self.filesTable.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
self.filesTable.setRowCount(len(self.currentItems))
self.filesTable.setColumnCount(4)
self.filesTable.setHorizontalHeaderLabels(['Name','TimeStamp','Type','ls -l'])
self.itemWidgets = [[],[],[],[]]
for i in range(len(self.currentItems)):
self.itemWidgets[0].append(QTableWidgetItem(self.currentItems[i]))
self.filesTable.setItem(i,0,self.itemWidgets[0][-1])
self.filesTable..connect(print)#self.updateUiCellClick)
self.itemWidgets[3].append(QTableWidgetItem(self.currentItemsLs[i]))
self.filesTable.setItem(i,3,self.itemWidgets[3][-1])
self.filesTable.resizeColumnsToContents()
self.setWindowTitle('{}'.format(self.currentPath))
def updateUiCellClick(self, row, column):
'''self.updateUiCellClick - None'''
print('self.updateUiCellClick - None')
self.currentpath += self.itemWidgets[0][row].text+'/'
self.updateUi()
print(' | Done')
if __name__ == '__main__':
print('i Execute instance')
app = QApplication(sys.argv)
root = root()
root.show()
app.exec_()
print(' | Done')
The connection should be as follows
self.filesTable.cellClicked.connect(self.updateUiCellClick)
^^^^^^^^^^^
signal
In addition to this it is not necessary to create the connection every time you fill in the table, it is enough when you create it.
If you look at code you see that many parts are repeating, which is not necessary, I take the boldness to make improvements to your code as the verification of path and reduce the code.
import sys
import os
from subprocess import Popen, PIPE
from PyQt5.QtWidgets import *
class Root(QMainWindow):
def __init__(self, parent=None):
print(' self.__init__ - Initializes QMainWindow')
QMainWindow.__init__(self, parent)
# Create Table Widget
self.filesTable = QTableWidget()
self.filesTable.cellClicked.connect(self.updateUiCellClick)
# Init Table Widget
self.filesTable.clear()
self.filesTable.setSizeAdjustPolicy(QTableWidget.AdjustToContents)
self.filesTable.setColumnCount(4)
self.filesTable.setHorizontalHeaderLabels(['Name', 'TimeStamp', 'Type', 'ls -l'])
# Init Widgets
self.setCentralWidget(self.filesTable)
self.populate_table("/")
def populate_table(self, path):
# Verify that it is a directory.
if not os.path.isdir(path):
return
os.chdir(path)
current_items = os.listdir()
currentItemsLsProcess = Popen(['ls', '-l'], stdout=PIPE, stderr=PIPE)
currentItemsLsProcessResult = currentItemsLsProcess.communicate()
if currentItemsLsProcessResult[1].decode('utf-8'):
QMessageBox.warning(self, 'Files - ls -l Error',
'ls -l responded with non-blank stderr.Error is shown here:'
'<br><code>{}</code><br><hr><br>Error LsStderr (e-lsstderr)<br>'
'<hr><br>If you want to support the team, go to the '
'GitHub Repository.'.format(
currentItemsLsProcessResult[1].decode('utf-8')))
return
self.filesTable.clear()
currentItemsLs = currentItemsLsProcessResult[0].decode('utf-8').split('\n')[1:-1]
self.filesTable.setRowCount(len(current_items))
for i, values in enumerate(zip(current_items, currentItemsLs)):
name, ls = values
self.filesTable.setItem(i, 0, QTableWidgetItem(name))
self.filesTable.setItem(i, 3, QTableWidgetItem(ls))
self.setWindowTitle('{}'.format(path))
def updateUiCellClick(self, row, _):
path = os.path.join(os.getcwd(), self.filesTable.item(row, 0).text())
self.populate_table(path)
if __name__ == '__main__':
print('i Execute instance')
app = QApplication(sys.argv)
root = Root()
root.show()
status = app.exec_()
print(' | Done')
sys.exit(status)

Why does QFileSystemWatcher work for directories but not files in Python?

I borrowed this code from another StackOverflow answer:
from PyQt4 import QtCore
#QtCore.pyqtSlot(str)
def directory_changed(path):
print('Directory Changed!!!')
#QtCore.pyqtSlot(str)
def file_changed(path):
print('File Changed!!!')
fs_watcher = QtCore.QFileSystemWatcher(['/path/to/files_1', '/path/to/files_2', '/path/to/files_3'])
fs_watcher.connect(fs_watcher, QtCore.SIGNAL('directoryChanged(QString)'), directory_changed)
fs_watcher.connect(fs_watcher, QtCore.SIGNAL('fileChanged(QString)'), file_changed)
The problem is, file_changed never gets called, no matter what. directory_changed is reliably called when a file is added, for example, but changing the files content does not result in file_changed being called.
I called a few variations of QtCore.SIGNAL('fileChanged(QString)'), eg, QtCore.SIGNAL('fileChanged(const QString &)'), to no avail. There are no warnings, or errors -- it simply does not trigger the function.
Recommendations?
It's hard to be certain what's going wrong, because the example code is incomplete, and so cannot work at all as it stands.
However, assuming the real code you are running is more or less sane/complete, your problem is probably caused by not adding the directory itself to the list of paths.
A basic script should look something like this:
import sys
from PyQt4 import QtCore
def directory_changed(path):
print('Directory Changed: %s' % path)
def file_changed(path):
print('File Changed: %s' % path)
app = QtCore.QCoreApplication(sys.argv)
paths = [
'/path/to',
'/path/to/files_1',
'/path/to/files_2',
'/path/to/files_3',
]
fs_watcher = QtCore.QFileSystemWatcher(paths)
fs_watcher.directoryChanged.connect(directory_changed)
fs_watcher.fileChanged.connect(file_changed)
sys.exit(app.exec_())
import argparse
import configparser
import os
import sys
from PyQt5 import QtCore
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QDesktopWidget, QMessageBox
from PyQt5.QtWidgets import QMainWindow
from ProgressBar_ui import Ui_Form
class ProgressBarWindow(QMainWindow, Ui_Form):
def __init__(self):
super().__init__()
self.ui = Ui_Form()
self.ui.setupUi(self)
self.ui.progressBar.setMinimum(0)
self.ui.progressBar.setMaximum(0)
self.ui.progressBar.setValue(0)
self.setWindowTitle("Progress Bar")
self.MSversion = ""
self.LOADING_LOG_PATH = ""
mainIco = ("Icons\myIcon.ico")
self.setWindowIcon(QIcon(mainIco))
self.ui.label.setText("")
self.ui.label.setWordWrap(True)
def location_on_the_screen(self):
ag = QDesktopWidget().availableGeometry()
sg = QDesktopWidget().screenGeometry()
widget = self.geometry()
x = ag.width() - widget.width()
y = 2 * ag.height() - sg.height() - widget.height()
self.move(x, y)
def file_changed(self, pathPassed):
if os.path.exists(pathPassed):
f = open(pathPassed, "r")
for x in f:
#print(x)
label =x
self.ui.label.setText(label)
if x == "CloseLoading":
self.close()
def main():
app = QApplication(sys.argv)
w = ProgressBarWindow()
w.setWindowFlags(w.windowFlags() & ~QtCore.Qt.WindowMaximizeButtonHint)
parser = argparse.ArgumentParser()
parser = argparse.ArgumentParser(description='ProgressBar Arguments')
parser.add_argument('version', action="store", type=str)
args = vars(parser.parse_args())
if len(sys.argv) < 1:
msg = QMessageBox()
msg.setIcon(QMessageBox.Critical)
errorMsg = "There are less than 2 command line arguments provided.\nLauncher can not be run."
msg.setText(errorMsg)
msg.setWindowTitle("Save paths..")
msg.exec_()
sys.exit()
p= '/path/toFile/'
paths = [ p ]
fs_watcher = QtCore.QFileSystemWatcher(paths)
#fs_watcher.directoryChanged.connect(w.directory_changed)
fs_watcher.fileChanged.connect(w.file_changed)
w.location_on_the_screen()
w.show()
app.exec_()
if __name__ == "__main__":
sys.exit(main())

Refresh QTextEdit in PyQt

Im writing a PyQt app that takes some input in one widget, and then processes some text files.
What ive got at the moment is when the user clicks the "process" button a seperate window with a QTextEdit in it pops up, and ouputs some logging messages.
On Mac OS X this window is refreshed automatically and you cna see the process.
On Windows, the window reports (Not Responding) and then once all the proccessing is done, the log output is shown. Im assuming I need to refresh the window after each write into the log, and ive had a look around at using a timer. etc, but havnt had much luck in getting it working.
Below is the source code. It has two files, GUI.py which does all the GUI stuff and MOVtoMXF that does all the processing.
GUI.py
import os
import sys
import MOVtoMXF
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Form(QDialog):
def process(self):
path = str(self.pathBox.displayText())
if(path == ''):
QMessageBox.warning(self, "Empty Path", "You didnt fill something out.")
return
xmlFile = str(self.xmlFileBox.displayText())
if(xmlFile == ''):
QMessageBox.warning(self, "No XML file", "You didnt fill something.")
return
outFileName = str(self.outfileNameBox.displayText())
if(outFileName == ''):
QMessageBox.warning(self, "No Output File", "You didnt do something")
return
print path + " " + xmlFile + " " + outFileName
mov1 = MOVtoMXF.MOVtoMXF(path, xmlFile, outFileName, self.log)
self.log.show()
rc = mov1.ScanFile()
if( rc < 0):
print "something happened"
#self.done(0)
def __init__(self, parent=None):
super(Form, self).__init__(parent)
self.log = Log()
self.pathLabel = QLabel("P2 Path:")
self.pathBox = QLineEdit("")
self.pathBrowseB = QPushButton("Browse")
self.pathLayout = QHBoxLayout()
self.pathLayout.addStretch()
self.pathLayout.addWidget(self.pathLabel)
self.pathLayout.addWidget(self.pathBox)
self.pathLayout.addWidget(self.pathBrowseB)
self.xmlLabel = QLabel("FCP XML File:")
self.xmlFileBox = QLineEdit("")
self.xmlFileBrowseB = QPushButton("Browse")
self.xmlLayout = QHBoxLayout()
self.xmlLayout.addStretch()
self.xmlLayout.addWidget(self.xmlLabel)
self.xmlLayout.addWidget(self.xmlFileBox)
self.xmlLayout.addWidget(self.xmlFileBrowseB)
self.outFileLabel = QLabel("Save to:")
self.outfileNameBox = QLineEdit("")
self.outputFileBrowseB = QPushButton("Browse")
self.outputLayout = QHBoxLayout()
self.outputLayout.addStretch()
self.outputLayout.addWidget(self.outFileLabel)
self.outputLayout.addWidget(self.outfileNameBox)
self.outputLayout.addWidget(self.outputFileBrowseB)
self.exitButton = QPushButton("Exit")
self.processButton = QPushButton("Process")
self.buttonLayout = QHBoxLayout()
#self.buttonLayout.addStretch()
self.buttonLayout.addWidget(self.exitButton)
self.buttonLayout.addWidget(self.processButton)
self.layout = QVBoxLayout()
self.layout.addLayout(self.pathLayout)
self.layout.addLayout(self.xmlLayout)
self.layout.addLayout(self.outputLayout)
self.layout.addLayout(self.buttonLayout)
self.setLayout(self.layout)
self.pathBox.setFocus()
self.setWindowTitle("MOVtoMXF")
self.connect(self.processButton, SIGNAL("clicked()"), self.process)
self.connect(self.exitButton, SIGNAL("clicked()"), self, SLOT("reject()"))
self.ConnectButtons()
class Log(QTextEdit):
def __init__(self, parent=None):
super(Log, self).__init__(parent)
self.timer = QTimer()
self.connect(self.timer, SIGNAL("timeout()"), self.updateText())
self.timer.start(2000)
def updateText(self):
print "update Called"
AND MOVtoMXF.py
import os
import sys
import time
import string
import FileUtils
import shutil
import re
class MOVtoMXF:
#Class to do the MOVtoMXF stuff.
def __init__(self, path, xmlFile, outputFile, edit):
self.MXFdict = {}
self.MOVDict = {}
self.path = path
self.xmlFile = xmlFile
self.outputFile = outputFile
self.outputDirectory = outputFile.rsplit('/',1)
self.outputDirectory = self.outputDirectory[0]
sys.stdout = OutLog( edit, sys.stdout)
class OutLog():
def __init__(self, edit, out=None, color=None):
"""(edit, out=None, color=None) -> can write stdout, stderr to a
QTextEdit.
edit = QTextEdit
out = alternate stream ( can be the original sys.stdout )
color = alternate color (i.e. color stderr a different color)
"""
self.edit = edit
self.out = None
self.color = color
def write(self, m):
if self.color:
tc = self.edit.textColor()
self.edit.setTextColor(self.color)
#self.edit.moveCursor(QtGui.QTextCursor.End)
self.edit.insertPlainText( m )
if self.color:
self.edit.setTextColor(tc)
if self.out:
self.out.write(m)
self.edit.show()
If any other code is needed (i think this is all that is needed) then just let me know.
Any Help would be great.
Mark
It looks like your are running an external program, capturing its output into a QTextEdit. I didn't see the code of Form.process, but I am guessing on windows your function waits for the external program to finish, then quickly dumps everything to the QTextEdit.
If your interface really is waiting for the other process to finish, then it will hang in the manner you describe. You'll need to look at subprocess or perhaps even popen to get the program's output in a "non-blocking" manner.
The key to avoiding "(Not Responding)" is to call QApplication.processEvents a few times every few seconds. The QTimer is not going to help in this case, because if Qt cannot process its events, it cannot call any signal handlers.

Categories

Resources