I seem to be hitting a brick wall. No matter what I do, creating a critical error Message Box just doesn't seem to be working. Here's what I've tried thus far:
flags = QtGui.QMessageBox.StandardButton.Abort
flags |= QtGui.QMessageBox.StandardButton.Ignore
result = QtGui.QMessageBox.critical(
self,
'CRITICAL ERROR',
'Error Message',
flags
)
As taken from this tutorial (old I know, but it's been helpful thus far). Doing this however, brings up the following error:
'PySide.QtGui.QMessageBox.critical' called with wrong argument types:
PySide.QtGui.QMessageBox.critical(CreateMessage, str,
StandardButtons)
Supported signatures:
PySide.QtGui.QMessageBox.critical(PySide.QtGui.QWidget, unicode,
unicode, PySide.QtGui.QMessageBox.StandardButtons = QMessageBox.Ok,
PySide.QtGui.QMessageBox.StandardButton = NoButton)
PySide.QtGui.QMessageBox.critical(PySide.QtGui.QWidget, unicode,
unicode, PySide.QtGui.QMessageBox.StandardButton,
PySide.QtGui.QMessageBox.StandardButton)
I've also tried the following:
result = QtGui.QMessageBox.critical(
self,
'CRITICAL ERROR',
'Error Message',
QtGui.QMessageBox.StandardButton.Abort
)
# Or this....
result = QtGui.QMessageBox.critical(
self,
'CRITICAL ERROR',
'Error Message',
QtGui.QMessageBox.Abort
)
None of these seem to work properly. How do I create a critical error message box?
Simple Example Below
import sys
from PySide import QtGui
app = QtGui.QApplication(sys.argv)
a=QtGui.QMessageBox.critical(None,'Error!',"Error Message!", QtGui.QMessageBox.Abort)
Here's an example from Qt.Gitorious.
from PySide import QtGui, QtCore
import sys
class Dialog(QtGui.QDialog):
MESSAGE = QtCore.QT_TR_NOOP("<p>Message boxes have a caption, a text, and up to "
"three buttons, each with standard or custom texts.</p>"
"<p>Click a button or press Esc.</p>")
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.criticalLabel = QtGui.QLabel()
self.criticalLabel.setFrameStyle(QtGui.QFrame.Sunken | QtGui.QFrame.Panel)
self.criticalButton = QtGui.QPushButton(self.tr("QMessageBox.critica&l()"))
layout = QtGui.QGridLayout()
layout.addWidget(self.criticalButton, 10, 0)
layout.addWidget(self.criticalLabel, 10, 1)
self.setLayout(layout)
self.connect(self.criticalButton, QtCore.SIGNAL("clicked()"), self.criticalMessage)
def criticalMessage(self):
reply = QtGui.QMessageBox.critical(self, self.tr("QMessageBox.showCritical()"),
Dialog.MESSAGE, QtGui.QMessageBox.Abort|
QtGui.QMessageBox.StandardButton.Retry|
QtGui.QMessageBox.StandardButton.Ignore)
if reply == QtGui.QMessageBox.Abort:
self.criticalLabel.setText(self.tr("Abort"))
elif reply == QtGui.QMessageBox.Retry:
self.criticalLabel.setText(self.tr("Retry"))
else:
self.criticalLabel.setText(self.tr("Ignore"))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
dialog = Dialog()
sys.exit(dialog.exec_())
To answer your question you can check the documentation:
static PySide.QtGui.QMessageBox.critical(parent, title, text[, buttons=QMessageBox.Ok[, defaultButton=NoButton]])
In the example, parent = self, title = self.tr("QMessageBox.showCritical()"), text = Dialog.MESSAGE, buttons = QtGui.QMessageBox.Abort | QtGui.QMessageBox.StandardButton.Retry | QtGui.QMessageBox.StandardButton.Ignore
The tr is just some Qt function to set up translations, basically its a string. I can't really tell you what you did wrong, looking at the error message, it seems to have parsed things wrong. Possibly because of the way you assigned values to flags.
The example also shows how to deal with the result of the critical dialog, which seems useful.
Related
I'm trying to get the Window ID of the SDL window, to give to VLC so it can play the video in the window.
Being new to Python, I'm vaguely aware this has to do with variable type conversions to play nice with SDL, and using the correct python binding...
The line with the error is "win_id = SDL_GetWindowID(window)"
Here is my code;
import sys
import sdl2.ext
import vlc
import ctypes
from sdl2 import *
RESOURCES = sdl2.ext.Resources(__file__, "resources")
sdl2.ext.init()
window = sdl2.ext.Window("Hello World!", size=(640, 480))
window.show()
factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE)
sprite = factory.from_image(RESOURCES.get_path("hello.bmp"))
spriterenderer = factory.create_sprite_render_system(window)
spriterenderer.render(sprite)
vlcInstance = vlc.Instance("--no-xlib")
player = vlcInstance.media_player_new()
win_id = SDL_GetWindowID(window)
player.set_xwindow(win_id)
player.set_mrl("agro.mp4")
player.play()
processor = sdl2.ext.TestEventProcessor()
processor.run(window)
sdl2.ext.quit()
What you get with SDL_GetWindowID is SDL's internal window ID that it itself refers to in e.g. events. What you need is X11 window ID, which you can get through SDL_GetWindowWMInfo. That however requires some trickery with SDL versioning, e.g. (I'm not sure it is safe to call that in python if SDL version changes but pysdl2 is not updated):
wminfo = SDL_SysWMinfo();
SDL_GetVersion(wminfo.version);
if(SDL_GetWindowWMInfo(window.window, wminfo) == 0):
print("can't get SDL WM info");
sys.exit(1);
win_id = wminfo.info.x11.window;
Then use that win_id to feed to vlc.
The issue is a combination of setting an icon on the action in the toolbar (or qpushbutton) and showing a qmessagebox when triggered. If I remove the icon, the message box displays. And if I remove the message box but keep the icon, the app stays open. The other odd thing is, if I add the icon to the push button but not the action, and click on the action, it still closes the app. The doubly odd thing is if I add main.qpush_button_clicked before qapplication.exec_(), the message box is displayed. However, the next time I click on either, it closes the app.
I have looked at multiple posts and some of the ideas were to use setQuitOnLastWindowClosed, but that did not fix the issue. I also implemented event to see what was happening. When I click on either of the items, it triggers a ChildAdded event, then closes.
Also, this only does not work when I use cx_Freeze on a Mac. I have not tried on Win. It works properly when run using Eclipse or from CLI.
Does anyone have any ideas on what might be causing this, or how to fix it besides not using icons.
The icon I used is from Android icon pack.
I can add the crash log if you need it.
class Main(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.qicon = QIcon('../ic_add_black_24dp_1x.png')
self.tool_bar = self.addToolBar('main')
qaction = QAction(self)
self.tool_bar.addAction(qaction)
qaction.setText('add')
qaction.setIcon(self.qicon)
qaction.triggered.connect(self.qpush_button_clicked)
qpush_button = QPushButton('add')
self.setCentralWidget(qpush_button)
qpush_button.setIcon(self.qicon)
qpush_button.clicked.connect(self.qpush_button_clicked)
def qpush_button_clicked(self, *args, **kwargs):
QMessageBox.critical(self, 'test', 'testing')
if __name__ == '__main__':
qapplication = QApplication(sys.argv)
main = Main()
main.show()
main.raise_()
qapplication.exec_()
And here is the setup file
name = 'dialog'
version = '0.1'
description = 'description'
packages = ('os',)
excludes = ('tkinter',)
include_files = ('ic_add_black_24dp_1x.png',)
build_exe = dict(packages=packages,
excludes=excludes,
include_files=include_files)
options = dict(build_exe=build_exe)
base = 'Win32GUI' if sys.platform == 'win32' else None
script = 'dialog.py'
executables = (Executable(script, base=base),)
setup(name=name,
version=version,
description=description,
options=options,
executables=executables)
PySide Version : 1.2.2
PySide Component: : (1, 2, 2, 'final', 0)
PySide Compiled Qt : 4.8.7
PySide Qt Component: (4, 8, 7)
Running Qt Version : 4.8.7
I'm writing a pyqt program utilising the Qwizard. From one screen I am running a thread and starting a command line program via Popen. However I'm getting the following warning message:
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
The program usually continues but crashes sporadically immediately after this point, leading me to feel that it is related.
As the code of the program is too much to attach, here are the relevant snippets:
class Fee(QThread):
def __init__(self, parent=None, options=None):
QThread.__init__(self, parent)
#set the given options
if options:
self.__options = options
def copy(self, devicename, outputfilename):
self.__device = devicename
self.__outputfile = outputfilename
self.start()
def run(self):
cmd = self.__getCommandLine(self.options, self.__device, self.__outputfile)
logging.info("Running Fee with command %s" % (cmd))
#start the process
output = ""
process = Popen(shlex.split(cmd), stdout= PIPE, stderr= STDOUT)
stderr = process.communicate()[1]
class FeeManager(QtCore.QObject):
def copyAndVerify(self):
self.__fee = Fee(self, self.options)
self.connect(self.__fee, QtCore.SIGNAL("finished()"), self._setCopyFinished)
self.connect(self.__fee, QtCore.SIGNAL("progressUpdated(QString, int, QString)"), self._setCopyProgress)
devicename = self.device.blockdevice
self.__image_outputfilename = "output_file.img")
self.__fee.copy(devicename, self.__image_outputfilename)
class FeeWizardPage(QtGui.QWizardPage):
def initializePage(self):
#already earlier in another wizard page is the following: self.feemanager = FeeManager(self, info)
self.connect(self.wizard().feemanager, QtCore.SIGNAL("copyProgressUpdated(QString, int, QString)"), self.updateCopyProgress)
self.connect(self.wizard().feemanager, QtCore.SIGNAL("verifyProgressUpdated(QString, int, QString)"), self.updateVerifyProgress)
self.connect(self.wizard().feemanager, QtCore.SIGNAL("finished(PyQt_PyObject)"), self.setDone)
self.wizard().feemanager.copyAndVerify()
What am I doing wrong? How can I avoid this message and hopefully bring some stability to the program. I've searched the internet and this forum, and while I've tried a number of suggestions for others, none have worked for this problem. Even when I comment out all signals and connects, I still get the same warning message.
Can someone help?
Thanks a lot.
I have the need to download all files in an ftp directory. I don't know the files in the dir at the time my program starts, so I want the program to list the contents of the dir, then download each of the files it finds.
I've made a little demo script that downloads a file from ftp & updates a progress bar while doing so. The downloading & updating the progress bar works fine, however, I'm trying to do the next step which is to list the contents of some dir & download the files, and that part isn't working.
At the moment, I'm just trying to do a list on any directory & print the results to the command line.
When I try to do a listInfo.connect, I get an error message:
QObject::connect: Cannot queue arguments of type 'QUrlInfo'
(Make sure 'QUrlInfo' is registered using qRegisterMetaType().)
... as I understand it, qRegisterMetaType is not something that can be done in PyQt & is also a sign of a fundamental problem, and herein lies my problem. I can do a commandFinished.connect and dataTransferProgress.connect without issue, but listInfo.connect doesn't seem to work (as I would expect it).
Any ideas how to correct this?
Here's some example code (pardon the length). I would like to be able to print the listed files/urls from the function "lister". Ultimately, I'd like to then have that function formulate new urls & pass them back to connectAndDownload to download each of the files (of course, this will require modifications to connectAndDownload, but we're not there yet).
#!/usr/bin/env python
from PyQt4 import QtCore, QtGui, QtNetwork
class FtpWorker(QtCore.QThread):
dataTransferProgress = QtCore.pyqtSignal(int,int)
def __init__(self,url,parent=None):
super(FtpWorker,self).__init__(parent)
self.ftp = None
self.outFile = None
self.get_index = -1
self.url = url
def run(self):
self.connectAndDownload()
self.exec_()
def ftpCommandFinished(self, command_index, error):
print "-----commandfinished-----",command_index
if self.ftp.currentCommand == QtNetwork.QFtp.ConnectToHost:
if error:
QtGui.QMessageBox.information(self, "FTP",
"Unable to connect to the FTP server at %s. Please "
"check that the host name is correct.")
return
if self.ftp.currentCommand == QtNetwork.QFtp.Get or command_index == self.get_index:
if error:
print "closing outfile prematurely"
self.outFile.close()
self.outFile.remove()
else:
print "closed outfile normally"
self.outFile.close()
self.outFile = None
def ftpDataTransferProgress(self,a,b):
self.dataTransferProgress.emit(a,b)
def lister(self,url_info):
print url_info.name()
def connectAndDownload(self):
if self.ftp:
self.ftp.abort()
self.ftp.deleteLater()
self.ftp = None
return
self.ftp = QtNetwork.QFtp()
self.ftp.commandFinished.connect(self.ftpCommandFinished)
self.ftp.listInfo.connect(self.lister)
self.ftp.dataTransferProgress.connect(self.ftpDataTransferProgress)
url = QtCore.QUrl(self.url)
print "connect",self.ftp.connectToHost(url.host(), url.port(21))
print "login",self.ftp.login(url.userName(), url.password())
print "Connecting to FTP server %s..." % str(url.host())
import os
fileName = os.path.basename(self.url)
if QtCore.QFile.exists(fileName):
print "removing '%s'" % fileName
os.unlink(fileName)
self.outFile = QtCore.QFile(fileName)
if not self.outFile.open(QtCore.QIODevice.WriteOnly):
QtGui.QMessageBox.information(self, "FTP",
"Unable to save the file %s: %s." % (fileName, self.outFile.errorString()))
self.outFile = None
return
tmp = self.ftp.list()
print "starting list",tmp
print "ftp.get(%s,%s)" % (str(url.path()), self.outFile)
self.get_index = self.ftp.get(url.path(), self.outFile)
class AddProgresWin(QtGui.QWidget):
def __init__(self, parent=None):
super(AddProgresWin, self).__init__(parent)
self.thread = FtpWorker(url="ftp://ftp.qt.nokia.com/developerguides/qteffects/screenshot.png")
self.thread.dataTransferProgress.connect(self.updateDataTransferProgress)
self.nameLabel = QtGui.QLabel("0.0%")
self.nameLine = QtGui.QLineEdit()
self.progressbar = QtGui.QProgressBar()
mainLayout = QtGui.QGridLayout()
mainLayout.addWidget(self.progressbar, 0, 0)
mainLayout.addWidget(self.nameLabel, 0, 1)
self.setLayout(mainLayout)
self.setWindowTitle("Processing")
self.thread.start()
def updateDataTransferProgress(self, readBytes, totalBytes):
self.progressbar.setMaximum(totalBytes)
self.progressbar.setValue(readBytes)
perct = "%2.1f%%" % (float(readBytes)/float(totalBytes)*100.0)
self.nameLabel.setText(perct)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.path)
pbarwin = AddProgresWin()
pbarwin.show()
sys.exit(app.exec_())
It appears that this is a Qt bug. From Phil Thompson, "It's arguably a Qt bug -it should call qRegisterMetaType() itself for any types used in signal arguments."
It was also brought to my attention that for this purpose, there's no need to thread, as QFtp is asynchronous & comes with its own signals. I've reimplemented the ftp.list() (and associated signal handling) in the main thread & all is well.
This is what happens:
code here:
self.connectAction = createAction(
self, "设备连接(&C)", self.setupDevice,
icon_id = QStyle.SP_DialogNoButton)
and this the createAction:
def createAction(parent,
text,
slot=None,
shortcut=None,
icon=None,
tip=None,
checkable=False,
signal="triggered()",
whatis=None,
icon_id=None):
action = QAction(text, parent)
if icon:
if isinstance(icon, QIcon):
action.setIcon(icon)
else:
action.setIcon(QIcon(":/%s.png" % icon))
if icon_id:
action.setIcon(app.style().standardIcon(icon_id))
if slot:
connect(action, signal, slot)
return action
OK, I found my problem, I set qt stylesheet, and it cause this problem.