I wrote a simple application in Python and PySide. When I run it, SIGNALs are not working.
The application starts without errors.
from PySide.QtCore import *
from PySide.QtGui import *
import sys
class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
dial = QDial()
dial.setNotchesVisible(True)
spinbox = QSpinBox()
layout = QHBoxLayout()
layout.addWidget(dial)
layout.addWidget(spinbox)
self.setLayout(layout)
self.connect(dial, SIGNAL("valueChaged(int)"), spinbox.setValue)
self.connect(spinbox, SIGNAL("valueChaged(int)"), dial.setValue)
self.setWindowTitle("Signals and Slots")
# END def __init__
# END class Form
def main():
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
# END def main
if __name__ == '__main__':
main()
# END if
I am using:
Pyside 1.2.2;
Python 2.7.6;
OS Centos; Windows 7
I am running the application with:
Sublime Text 3 and Eclipse Luna;
How can I make SIGNALs working?
Your signal name is incorrect;
Incorrect :
valueChaged (int)
Correct :
valueChanged (int)
Test it, work fine;
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class QFormDialog (QDialog):
def __init__(self, parent = None):
super(QFormDialog, self).__init__(parent)
self.myQial = QDial()
self.myQSpinbox = QSpinBox()
self.myQHBoxLayout = QHBoxLayout()
self.myQial.setNotchesVisible(True)
self.myQHBoxLayout.addWidget(self.myQial)
self.myQHBoxLayout.addWidget(self.myQSpinbox)
self.setLayout(self.myQHBoxLayout)
self.connect(self.myQial, SIGNAL('valueChanged(int)'), self.myQSpinbox.setValue)
self.connect(self.myQSpinbox, SIGNAL('valueChanged(int)'), self.myQial.setValue)
self.setWindowTitle('Signals and Slots')
if __name__ == '__main__':
myQApplication = QApplication(sys.argv)
myQFormDialog = QFormDialog()
myQFormDialog.show()
myQApplication.exec_()
Note : PyQt4 & PySide is same way to implemented.
Related
In my program i want to use key press event in list view.When i press the enter key then only my selected text will print..Can any one please tell me how to use key press event for list view.I tried with installEventFilter but this method showing non type error.
Given below is my code:
import sys
from PyQt4 import QtCore,QtGui
class List_View(QtGui.QMainWindow):
def __init__(self, parent=None):
super(List_View, self).__init__(parent)
self.listview = QtGui.QListView()
model = QtGui.QStandardItemModel(self.listview)
for i in ['linux', 'windows', 'mac os']:
model.appendRow(QtGui.QStandardItem(i))
self.listview.setModel(model)
self.listview.entered.connect(self.add_items)
widget = QtGui.QWidget()
self.setCentralWidget(widget)
vlay = QtGui.QVBoxLayout(widget)
vlay.addWidget(self.listview)
self.resize(400, 200)
def add_items(self):
pass #here i need to print particular item in list view
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
w = List_View()
w.show()
sys.exit(app.exec_())
I think you have not read the docs of the entered signal or you have not understood it, that signal only triggers when the mouse is on the item but for this you must activate the mouse tracking with self.listview.setMouseTracking(True)
A simple solution is to use a QShortcut:
import sys
from PyQt4 import QtCore,QtGui
class List_View(QtGui.QMainWindow):
def __init__(self, parent=None):
super(List_View, self).__init__(parent)
shorcut = QtGui.QShortcut(
QtGui.QKeySequence(QtCore.Qt.Key_Return),
self
)
shorcut.activated.connect(self.on_enter_pressed)
self.listview = QtGui.QListView()
model = QtGui.QStandardItemModel(self.listview)
for i in ['linux', 'windows', 'mac os']:
model.appendRow(QtGui.QStandardItem(i))
self.listview.setModel(model)
widget = QtGui.QWidget()
self.setCentralWidget(widget)
vlay = QtGui.QVBoxLayout(widget)
vlay.addWidget(self.listview)
self.resize(400, 200)
#QtCore.pyqtSlot()
def on_enter_pressed(self):
print("enter press")
ix = self.listview.selectionModel().currentIndex()
print(ix.data())
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
w = List_View()
w.show()
sys.exit(app.exec_())
I have a class called app.py within that class there's a method called print_raw_records_screen here's the part of the class and the method
app.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
from Tkinter import *
from ttk import *
import os
import mftsession
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.filename = ""
self.initUI()
#defining a function that that receives the raw records from the mftsession.py and print it to the screen
#this script will be called by the mftsession.py in
#process_mftfile()
def print_raw_records_screen(self,records):
self.area.delete(1.0, "end")
self.area.insert('1.0',records)
def initUI(self):
self.parent.title("Mtf Analyzer")
#initializing and configuring menubar
menubar = Menu(self.parent)
self.parent.config(menu=menubar)
fileMenu = Menu(menubar)
fileMenu.add_command(label="Open file", command=self.fileOpen)
fileMenu.add_command(label="Exit", command=self.onExit)
menubar.add_cascade(label="File", menu=fileMenu)
#specify grid row and column spaces
self.pack(fill=BOTH, expand=True)
self.columnconfigure(1, weight=1)
self.columnconfigure(3, pad=7)
self.rowconfigure(3, weight=1)
self.rowconfigure(5, pad=7)
lbl = Label(self, text="File Name")
lbl.grid(row=1, column=0, sticky=W, pady=4, padx=5)
self.filename_area = Entry(self)
self.filename_area.grid(row=1, column=1, columnspan=5, padx=5, sticky=E+W+S+N)
analize_button = Button(self, text="Analize", command=self.processFile)
analize_button.grid(row=1, column=6, padx=5)
self.area = Text(self)
self.area.grid(row=2, column=1, columnspan=2, rowspan=4,
padx=5, sticky=E+W+S+N)
#configure the raw output view
def onExit(self):
self.quit()
#this function selects and opens the file to analize
def fileOpen(self):
from tkFileDialog import askopenfilename
Tk().withdraw()
self.filename = askopenfilename()
#populate the filename field
self.set( self.filename)
#do the processing of the file obtained. Populate the file NAME entry or
#send the filename to the analyzeMFT.py
def processFile(self):
arguments = "analyzeMFT.py -f "+self.filename+" -d --bodyfull -l -o "+self.filename+".csv"
os.system(arguments)
mftsession.MftSession.process_mft_file(self)
#get and set methods for the entry field
def get(self):
return self.filename_area.get()
def set(self, value):
self.filename_area.delete(0, END)
self.filename_area.insert(0,value)
def main():
root = Tk()
root.geometry("450x350+500+500")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
This method is called by another external script like this
mftsession.py
import csv
import json
import os
import sys
from optparse import OptionParser
import mft
import app
from Tkinter import *
from ttk import *
class MftSession:
"""Class to describe an entire MFT processing session"""
#staticmethod
def fmt_excel(date_str):
return '="{}"'.format(date_str)
#staticmethod
def fmt_norm(date_str):
return date_str
def __init__(self):
self.mft = {}
self.fullmft = {}
self.folders = {}
self.debug = False
self.mftsize = 0
def process_mft_file(self):
root = Tk()
appi = app.Example(root)
self.sizecheck()
self.build_filepaths()
# reset the file reading
self.num_records = 0
self.file_mft.seek(0)
raw_record = self.file_mft.read(1024)
if self.options.output is not None:
self.file_csv.writerow(mft.mft_to_csv(None, True, self.options))
while raw_record != "":
record = mft.parse_record(raw_record, self.options)
if self.options.debug:
print record
appi.print_raw_records_screen(raw_record ) #THIS FUNCTION WHILE INVOKED THIS WAY IS NOT WORKING
..........
The script analyzeMFT.py called by the app.py through the subrouting
#!/usr/bin/python
import sys
from os import path
def main():
session = mftsession.MftSession()
session.mft_options()
session.open_files()
session.process_mft_file()
if __name__ == '__main__':
if __package__ is None:
sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )
import mftsession
main()
else:
import mftsession
main()
When called this way it prints nothing to the window, but when i invoke it for testing within its own class it prints the test
def print_raw_records_screen(self,records):
self.area.delete(1.0, "end")
self.area.insert('1.0', records)
and invoke like print_raw_records_screen("any test"): in the app.py
An image can tell alot. and summarize
What am i doing wrong? I sense it's the instantiation am doing wrong. I need diretions please
From what I can see here you have a few issues causing problems.
you are importing app.py on mftsession.py instead importing mftsession.py on app.py.
You are trying to use appi.print_raw_records_screen(raw_record) on a completely different instance of the Example() class with appi = app.Example(root) remove that part all together.
It is bad practice to importing inside a function. Import at the start of each py file.
There is so many things going on in your code I had to create a Minimal, Complete, and Verifiable example example of my own to illustrate the relation between files.
Here is a simple example of how the 2 files can interact and the way I think you are trying to do things.
Here I have created a main file called app.py:
from Tkinter import *
# You might need to import the py file with the package name as well.
# Change the package name to the package your python files are located in.
import PACKAGE_NAME.file_b
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.filename = ""
analize_button = Button(self.parent, text="Analize", command=self.processFile)
analize_button.pack()
self.area = Text(self.parent, height = 2, width = 40)
self.area.pack()
def print_raw_records_screen(self,records):
self.area.delete(1.0, "end")
self.area.insert('1.0',records)
def processFile(self):
PACKAGE_NAME.file_b.process_mft_file(self)
if __name__ == "__main__":
root = Tk()
app = Example(root)
root.mainloop()
Here I have created a file called file_b.py
from Tkinter import *
def process_mft_file(self):
record = "Some values assigned to a variable"
self.print_raw_records_screen(record)
The results look something like this:
I have a simple Tkinter, Matplotlib python program. I am using Windows 10 and the program works fine until I close the window. Upon restarting the script I recieve a runtime error (see image). I tried to "contact the application's support team for more information" then I realized that I am the application support team....
#!/usr/bin/env python
import matplotlib
import time
matplotlib.use('TkAgg')
from numpy import arange, sin, pi
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from tkFileDialog import *
import sys
import Tkinter as Tk
def destroy(e):
sys.exit()
class Window():
def __init__(self):
self.root = Tk.Tk()
self.root.wm_title("Embedding in TK")
self.QuitButton = None
self.UploadButton = None
self.filepath = None
self.fig = None
self.canvas = None
self.image = None
def showWindow(self):
self.root.mainloop()
def addQuitButton(self, ButtonText):
if self.QuitButton is None:
self.QuitButton = Tk.Button(master = self.root, text = ButtonText, command = self.closeWindow)
self.QuitButton.pack(side=Tk.BOTTOM)
def addUploadButton(self, ButtonText):
if self.UploadButton is None:
self.UploadButton = Tk.Button(master = self.root, text = ButtonText, command = self.showFileDialog)
self.UploadButton.pack(side=Tk.BOTTOM)
def showFileDialog(self):
print 'oh yeah'
if self.filepath is None:
print 'Oh no...'
self.filepath = askopenfilename(parent=self.root)
print self.filepath
self.image = mpimg.imread(self.filepath)
self.buildFigure()
self.showCanvas()
def buildFigure(self):
self.fig = plt.figure()
self.im = plt.imshow(self.image)
def showCanvas(self):
self.canvas = FigureCanvasTkAgg(self.fig, master=self.root)
self.canvas.show()
self.canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
def closeWindow(self):
#sys.exit()
self.root.quit()
self.root.destroy()
if __name__== "__main__":
base = Window()
base.addQuitButton("Quit")
base.addUploadButton("Upload")
base.showWindow()
I found that Idle was the problem, though I don't know why. When I run my script in command line it has no problem.
I think my issue is simple, but I have hit a brick wall. I am not a programmer but needed a program to control a laser engraver via Arduino. My Original code was mostly working, but I wanted the ability to select a serial port with a QComboBox so I can make it software available for everyone.
I figured out how to do that with the code below:
import sys
import serial
import time
import serial.tools.list_ports
from PyQt4 import QtGui
from window_test import Ui_MainWindow
class Main(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.btn_laser_poweron.clicked.connect(self.btnFIRE)
self.ui.btn_laser_poweroff.clicked.connect(self.btnOFF)
self.ui.btn_lig_power.clicked.connect(self.btnLIG)
self.ui.btn_cutting_power.clicked.connect(self.btnCUT)
self.ui.btn_power_meter.clicked.connect(self.btnTEST)
self.ui.spinBox.valueChanged.connect(self.PwrLevel)
self.ui.comboBox.activated.connect(self.srlprt)
def srlprt(self):
serial.Serial(str(self.ui.comboBox.currentText()))
def btnFIRE(self):
ser.write("a" + chr(255))
def btnOFF(self):
ser.write("b" + chr(0))
def btnTEST(self):
ser.write("c" + chr(0))
time.sleep(59.5)
ser.write("d" + chr(255))
def btnLIG(self):
ser.write("e" + chr(29))
def btnCUT(self):
ser.write("f" + chr(160))
def PwrLevel(self):
val = self.ui.spinBox.value()
ser.write("g" + chr(val))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Main()
window.show()
sys.exit(app.exec_())
Now my problem is that none of my buttons work because "ser" is not globally defined. I understand that I broke that when I removed "ser = serial.Serial(port=COM3)" when it was above the class definition, but I don't know how to fix it. Any help would be greatly appreciated.
Cheers!
A simple solution would be to just set ser as attribute of your Main instance. Also it couldn't hurt to close the serial connection if it is open before opening a new one, e.g:
import sys
import serial
import time
import serial.tools.list_ports
from PyQt4 import QtGui
from window_test import Ui_MainWindow
class Main(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ser = None
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.btn_laser_poweron.clicked.connect(self.btnFIRE)
self.ui.btn_laser_poweroff.clicked.connect(self.btnOFF)
self.ui.btn_lig_power.clicked.connect(self.btnLIG)
self.ui.btn_cutting_power.clicked.connect(self.btnCUT)
self.ui.btn_power_meter.clicked.connect(self.btnTEST)
self.ui.spinBox.valueChanged.connect(self.PwrLevel)
self.ui.comboBox.activated.connect(self.srlprt)
def srlprt(self):
if self.ser:
self.ser.close()
self.ser = serial.Serial(str(self.ui.comboBox.currentText()))
def btnFIRE(self):
self.ser.write("a" + chr(255))
def btnOFF(self):
self.ser.write("b" + chr(0))
def btnTEST(self):
self.ser.write("c" + chr(0))
time.sleep(59.5)
self.ser.write("d" + chr(255))
def btnLIG(self):
self.ser.write("e" + chr(29))
def btnCUT(self):
self.ser.write("f" + chr(160))
def PwrLevel(self):
val = self.ui.spinBox.value()
self.ser.write("g" + chr(val))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Main()
window.show()
sys.exit(app.exec_())
I have an error in my Python code, I'm new to Python, and I'm also new to PyQT. What I'm trying to do is build a basic http proxy server with a GUI. I've done it in the console, but when I tried to implement a GUI, I'm getting an error.
Here is my code, any help is appreciated.
import BaseHTTPServer, SocketServer,sys
from PyQt4 import QtCore, QtGui
from Ui_MiniGui import Ui_MainWindow
class ThreadingHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
pass
class webServer(QtCore.QThread):
log = QtCore.pyqtSignal(object)
def __init__(self, parent = None):
QtCore.QThread.__init__(self, parent)
def run(self):
self.log.emit("Listening On Port 1805")
Handler = BaseHTTPServer.BaseHTTPRequestHandler
def do_METHOD(self):
method = self.command
#I got some trouble here, how can i emit the signal back to the log?
#self.log.emit(method) not work, python not crash
#webServer.log.emit(method) not work, python not crash
#below one not work and python crashes immediately
webServer().log.emit(method)
Handler.do_GET = do_METHOD
self.httpd = ThreadingHTTPServer(("", 1805), Handler)
self.httpd.serve_forever()
class Form(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.server = webServer()
self.server.log.connect(self.write_to_textEdit)
self.server.start()
def write_to_textEdit(self, data):
print data
self.ui.textEdit.setText(data)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = Form()
myapp.show()
sys.exit(app.exec_())
In this line
webServer().log.emit(method)
You create a new webserver instance and emit it's log signal. As this is a new object, this signal hasn't been connected to anything, so it's doing nothing.
To emit the signal on the right object, you could do the following:
def run(self):
...
server = self
def do_METHOD(self):
...
server.log.emit(self)