How to display a custom dialog using PyQt and QtDesigner to design the custom dialog? - pyqt

I have designed 2 widgets - one is the main application widget and a custom widget which would allow me to set the preferences in my main application. They are named - main and child.
Now, I can't get the child widget to show when I click the button in the main application.
Tried to learn from the Rapid GUI programming using Python and Qt book, but the example given there is for a hand coded form and not designed using QtDesigner. I am getting confused. Kindly help.
My code so far is this-
import serial, sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from main import Ui_Form # main.py and child.py are the ui
from child import Ui_Form as Child_Form # files generated using pyuic4
class Main(QMainWindow):
def __init__(self, parent = None):
super(Main, self).__init__(parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
self.connect(self.ui.btnLaunch, SIGNAL("clicked()"), self.show)
def show(self):
dialog = QDialog()
dialog.ui = Child_Form()
dialog.ui.setupUi(self)
if __name__ == "__main__":
app = QApplication(sys.argv)
myapp = Main()
myapp.show()
sys.exit(app.exec_())
However, nothing happens when I try to launch this program.

Instead of this code:
self.connect(self.ui.btnLaunch, SIGNAL("clicked()"), self.show)
def show(self):
dialog = QDialog()
dialog.ui = Child_Form()
dialog.ui.setupUi(self)
try with this, it should work:
self.connect(self.ui.btnLaunch, SIGNAL("clicked()"), self.showDialog)
def showDialog(self):
dialog = QDialog()
dialog.ui = Child_Form()
dialog.ui.setupUi(self)
dialog.show()

Related

slot to right click menu action does does not work

I have written the below code to which I finally managed to add menu but connecitn menu to a function doesnt seem to work:
import os
from PyQt5 import uic
from PyQt5 import QtWidgets
from PyQt5 import QtCore
FILE_LOCATION = os.path.dirname(os.path.realpath(__file__))
class MainDialogWindow(QtWidgets.QDialog):
def __init__(self):
super(MainDialogWindow,self).__init__()
ui_file = os.path.join(FILE_LOCATION, "example.ui")
self._ui = uic.loadUi(ui_file, self)
self.registerCallbacks()
self.initUI()
def initUI(self):
"""Initialize the UI.
"""
self.textBrowser.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
def registerCallbacks(self):
self.textBrowser.customContextMenuRequested.connect(self.context_menu)
# self.connect(self.textBrowser, QtCore.Signal('customContextMenuRequested(const QPoint &)'), self.context_menu)
def context_menu(self, pos):
menu = QtWidgets.QMenu(self)
action = menu.addAction("clear")
menu.exec_(self.mapToGlobal(pos))
action.trigered.connect(self.clear)
def clear(self):
"""Slot to claer text.
"""
print("clear")
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = MainDialogWindow()
window.show()
window.setGeometry(500, 300, 300, 300)
sys.exit(app.exec_())
please helpp,, I want call the clear function from the right click menu
I don't seem to understand how the menu.exec_() method works, that method blocks the execution of sequential tasks until the user selects a QAction from the QMenu. In your case, for example, until when you press "clear" and the triggered signal is emitted (note: you have a typo), but at that moment there is no connection, so the clear method will not be called. The solution is to make the connection before invoking the QMenu exec_():
def context_menu(self, pos):
menu = QtWidgets.QMenu(self)
action = menu.addAction("clear")
action.triggered.connect(self.clear)
menu.exec_(self.mapToGlobal(pos))

Start the script in PyQt5 and python3 [duplicate]

I have created a form using PyQt4 which has a push button. On this push button I want to call another python script which looks like this:
File1.py:
import sys
from PyQt4 import QtCore, QtGui
from file1_ui import Ui_Form
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = MyForm()
myapp.show()
sys.exit(app.exec_())
File1_ui.py
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName(_fromUtf8("Form"))
Form.resize(400, 300)
self.pushButton = QtGui.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(120, 200, 95, 20))
self.pushButton.setObjectName(_fromUtf8("pushButton"))
self.retranslateUi(Form)
QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), Form.close)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate("Form", "Close", None, QtGui.QApplication.UnicodeUTF8))
File2.py
import sys
from PyQt4 import Qt
from taurus.qt.qtgui.application import TaurusApplication
app = TaurusApplication(sys.argv)
panel = Qt.QWidget()
layout = Qt.QHBoxLayout()
panel.setLayout(layout)
from taurus.qt.qtgui.panel import TaurusForm
panel = TaurusForm()
model = [ 'test/i1/1/%s' % p for p in props ]
panel.setModel(model)
panel.show()
sys.exit(app.exec_())
File1_ui.py is created from the Qtdesigner and then I am using File1.py to execute it.So File2.py when executed alone opens up a panel and displays few attributes.I want this script to be called on the button click in the first form(file1.py) which I created using Qtdesigner.Could you let me know how I could achieve this functionality.Thanks.
You will need to make some modifications to File2.py to make the appropriate calls depending on whether it is running standalone or not. When you are launching the script via File1.py there will already be a QApplication instance with event loop running, so trying to create another and run its event loop will cause problems.
Firstly, move the core part of your script into its own function. This will allow you to easily call it from File1.py. You can then handle the case where the script is running standalone and needs to create a QApplication instance and start its event loop. (I am not familiar the the taurus library you are using, but you can probably substitute TaurusApplication for QtGui.QApplication)
File2.py:
import sys
from PyQt4 import QtCore, QtGui
def runscript():
panel = QtGui.QWidget()
layout = QtGui.QHBoxLayout(panel)
return panel # Must return reference or panel will be deleted upon return
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
panel = runscript()
panel.show()
sys.exit(app.exec_())
Assuming your files are in the same directory you can simply write import File2 and use File2.runscript() to run your code. You then just need to connect the function to your pushbuttons clicked() signal to run it. The only problem here is that the reference to the QWidget returned from the runscript() function will be lost (and the object deleted) if you connect directly to runscript(). For this reason I created a method launch_script() which saves a reference in MyForm.
File1.py:
import sys
from PyQt4 import QtCore, QtGui
from file1_ui import Ui_Form
import File2
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
# This is a bit of a hack.
self.ui.pushButton.clicked.connect(self.launch_script)
def launch_script(self):
self.panel = File2.runscript()
self.panel.show()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = MyForm()
myapp.show()
sys.exit(app.exec_())
I don't use Qt Designer, so I don't know the correct way to go about connecting the signal to launch_script(). The code I have written should work, but obviously violates OOP principles and is dependent on the name of the pushbutton widget assigned by the software.

How to insert VLC instance into a QFrame

I'm trying to make a simple video player app by embedding a VLC instance inside a PyQt widget (a QFrame). I found a few examples that go me going, but my code doesn't quite work. When I launch it, it plays "test_video.mp4", but it launches the regular VLC player app in its own, separate window. When I close out of the VLC player window, obviously the video stops, but the audio continues playing until I close my own Qt (PyQt) window.
edit 1: Forgot to mention I am using python-vlc, downloaded via pip.
### video_player.py
import sys
import vlc
from PyQt4 import QtCore, QtGui
from video_player_main_window import Ui_MainWindow
class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.vlc_instance = vlc.Instance("--no-xlib --sout-all")
self.mediaplayer = self.vlc_instance.media_player_new()
self.mediaplayer.set_xwindow(self.ui.video_frame.winId())
print(self.ui.video_frame.winId())
self.media_path = "test_video.mp4"
self.media = self.vlc_instance.media_new(self.media_path)
self.mediaplayer = self.vlc_instance.media_player_new()
self.mediaplayer.set_media(self.media)
self.mediaplayer.play()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = StartQT4()
myapp.show()
sys.exit(app.exec_())
I added a "print(self.ui.video_frame.win())" just for debugging / sanity check to make sure that was a legitimate value. Command line output below. The "X server failure" shows up after I close the VLC window while my PyQt window is still running.
### command line output
106954771
[00007f9c48055168] vdpau_avcodec generic error: Xlib is required for VDPAU
[00007f9c3c003968] xcb_window window error: X server failure
The "video_player_main_window" is the module that QtDesigner (+ pyuic4) generates. "video_frame" is the name of the QFrame object I'm trying to put the VLC instance into. See full code for video_player_main_window.py here: http://pastebin.com/cHpAHZN2
how if like this :
import sys
import vlc
from PyQt4 import QtCore, QtGui
from video_player_main_window import Ui_MainWindow
class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.vlc_instance = vlc.Instance()
self.mediaplayer = self.vlc_instance.media_player_new()
self.mediaplayer.set_hwnd(int(self.frame.winId()))
self.media_path = "test_video.mp4"
self.media = self.vlc_instance.media_new(self.media_path)
self.media.get_mrl()
self.mediaplayer.set_media(self.media)
self.mediaplayer.play()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = StartQT4()
myapp.show()
sys.exit(app.exec_())
i usualy use this for my simple player.

add pyqtgraph (plot) into QApplication

hy,
soooo, i created the MainWindow.ui file with the QTDesigner. Then i import this gui with following command into my .py file:
form_class = uic.loadUiType("ess_project.ui")[0]
What is the difference if i compile this .ui file with pyuic4 ?
(every time i compiled my .ui file i got following error:
RuntimeError: the sip module implements API v11.0 to v11.1 but the PyQt4.QtCore module requires API v10.1
The MainWindow create the first window, where all buttons etc. are placed.
class MainWindow(QtGui.QMainWindow, form_class):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
PlotWindow.__init__(self)
self.setupUi(self)
self.pb_send.clicked.connect(self.pb_send_clicked)
self.pb_open.clicked.connect(self.pb_open_clicked)
self.pb_exit.clicked.connect(self.pb_exit_clicked)
self.comboBox.currentIndexChanged.connect(self.combo_box_changed)
furthermore i have a second class named "PlotWindow". This class looks like this:
class PlotWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.w = QtGui.QMainWindow()
self.cw = pg.GraphicsLayoutWidget()
self.w.show()
self.w.resize(900,600)
self.w.setCentralWidget(self.cw)
self.w.setWindowTitle('pyqtgraph: G-CODE')
self.p = self.cw.addPlot(row=0, col=0)
now as you can see, the PloWindow - class create a second Window.
How can i implement the pg.GraphicsLayoutWidget() into the MainWindow - class ??
not sure if this can help you ?!? :
def main():
app = QtGui.QApplication([])
myWindow = MainWindow(None)
myWindow.show()
app.exec_()
if __name__ == '__main__':
main()
I am using python3 !!!
feel FREE to comment :)
thanks !
To place any pyqtgraph widgets inside your application, you add a placeholder widget and "promote" it to the pg class that you want. See: http://www.pyqtgraph.org/documentation/how_to_use.html#embedding-widgets-inside-pyqt-applications

PyQt4 tray icon application context menu items don't work

I've got a simple tray icon application, but "About" context menu item doesn't work at all.
I'm definitly mising something simple, but important here.
The question is what should i fix to see "About" menu item working?
import sys
from PyQt4 import QtCore
from PyQt4 import QtGui
class SystemTrayIcon(QtGui.QSystemTrayIcon):
def __init__(self, parent=None):
QtGui.QSystemTrayIcon.__init__(self, parent)
self.setIcon(QtGui.QIcon("icon.png"))
self.iconMenu = QtGui.QMenu(parent)
appabout = self.iconMenu.addAction("About")
appexit = self.iconMenu.addAction("Exit")
self.setContextMenu(self.iconMenu)
self.connect(appabout,QtCore.SIGNAL('triggered()'),self.showAbout)
self.connect(appexit,QtCore.SIGNAL('triggered()'),self.appExit)
self.show()
def showAbout(self):
QtGui.QMessageBox.information(self, self.tr("About app"), self.tr("My text here."))
def appExit(self):
sys.exit()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
trayIcon = SystemTrayIcon()
trayIcon.show()
sys.exit(app.exec_())
My solution is
def showAbout(self):
QtGui.QMessageBox.information(QtGui.QWidget(), self.tr("About Tunarium"), self.tr("Your text here."))

Resources