我有一个产生一些数据的线程(一个python列表),它可用于一个小部件,它将读取并显示主线程中的数据.实际上,我正在使用QMutex以这种方式提供对数据的访问:
class Thread(QThread):
def get_data(self):
QMutexLock(self.mutex)
return deepcopy(self.data)
def set_data(self, data):
QMutexLock(self.mutex)
self.data = deepcopy(data)
def run(self):
self.mutex = QMutex()
while True:
self.data = slowly_produce_data()
self.emit(SIGNAL("dataReady()"))
class Widget(QWidget):
def __init__(self):
self.thread = Thread()
self.connect(self.thread, SIGNAL("dataReady()"), self.get_data)
self.thread.start()
def get_data(self):
self.data = self.thread.get_data()
def paintEvent(self, event):
paint_somehow(self.data)
Run Code Online (Sandbox Code Playgroud)
请注意,我没有传递数据,emit()因为它们是通用数据(我试图使用PyObject作为数据类型,但是双重free()会使程序崩溃),但我正在用a复制数据deepcopy()(假设数据可以是像这样复制).我使用了deepcopy()因为我猜代码如下:
def get_data(self):
QMutexLock(self.mutex)
return self.data
Run Code Online (Sandbox Code Playgroud)
只复制对数据的引用(对吗?),数据将在返回后共享和解锁...这段代码是否正确?如果数据非常大(如1'000'000项列表),我该怎么办?
谢谢.
PS我看到了一些例子,比如Qt Mandelbrot例子,或PyQt的线程示例,但是他们在插槽中使用QImage作为参数.
我正在使用python和Qt编写GUI应用程序.当我在Mac上启动我的应用程序时,屏幕顶部Mac菜单栏中的第一个菜单项是"Python".我更喜欢那里的应用程序名称是我的应用程序的名称.我怎样才能获得我的程序名称?
以下演示程序创建了一个包含两个菜单的窗口:"Python"和"Foo".我不喜欢这样,因为无论我是用python还是COBOL编写应用程序,我的用户都没有区别.相反,我想要菜单"MyApp"和"Foo".
#!/usr/bin/python
# This example demonstrates unwanted "Python"
# application menu name on Mac.
# Makes no difference whether we use PySide or PyQt4
from PySide.QtGui import *
# from PyQt4.QtGui import *
import sys
app = QApplication(sys.argv)
# Mac menubar application menu is always "Python".
# I want "DesiredAppTitle" instead.
# setApplicationName() does not affect Mac menu bar.
app.setApplicationName("DesiredAppTitle")
win = QMainWindow()
# need None parent for menubar on Mac to get custom menus at all
mbar = …Run Code Online (Sandbox Code Playgroud) 我有一个PySide(Qt)GUI,它产生多个线程.线程有时需要更新GUI.我通过以下方式解决了这个问题:
class Signaller(QtCore.QObject) :
my_signal = QtCore.Signal(QListWidgetItem, QIcon)
signaller = Signaller()
class MyThread(threading.Thread):
def __init__(self):
super(IconThread, self).__init__()
# ...
def run(self) :
# ...
# Need to update the GUI
signaller.my_signal.emit(self.item, icon)
#
# MAIN WINDOW
#
class Main(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
# ...
# Connect signals
signaller.my_signal.connect(self.my_handler)
@QtCore.Slot(QListWidgetItem, QIcon)
def my_handler(self, item, icon):
item.setIcon(icon)
def do_something(self, address):
# ...
# Start new thread
my_thread = MyThread(newItem)
my_thread.start()
# ...
Run Code Online (Sandbox Code Playgroud)
有没有更简单的方法?创建信号,处理程序和连接它们需要几行代码.
我用pyInstaller编译的python程序结果超过400 MB.该程序的GUI基于htmlPY,它是"PySide的QtWebKit库的包装器".该程序的大尺寸部分归功于它利用numpy,scipy和nltk,部分原因是图形库.
为了最小化程序的大小,我安装了UPX.这将程序的大小减小到略超过100MB,这很大,但可以接受.
第一个问题是pyInstaller没有检测到htmlPy,并且没有将它包含在已编译的程序中.这可以通过将我的Python安装中的htmlPy模块复制到pyInstaller创建的'dist'目录中来解决.这样做之后,没有UPX编译的程序版本运行正常.
将htmlPy添加到'dist'目录后,运行可执行文件会在创建GUI时崩溃程序.我不确定这是否是由于UPX和QT之间或UPX,QT和htmlPy之间存在问题.Windows"问题签名"如下:
Problem signature:
Problem Event Name: APPCRASH
Application Name: main.exe
Application Version: 0.0.0.0
Application Timestamp: 00000000
Fault Module Name: QtCore4.dll
Fault Module Version: 4.8.7.0
Fault Module Timestamp: 561e435a
Exception Code: c0000005
Exception Offset: 000000000010883a
Run Code Online (Sandbox Code Playgroud)
关于这里发生了什么,以及如何解决它的想法?
编辑:
这些是我的.spec文件的内容:
# -*- mode: python -*-
block_cipher = None
added_files = [
( 'htmlPy/binder.js', 'htmlPy' ),
( 'templates/*', 'templates' ),
]
a = Analysis(['main.py'],
pathex=['C:\\..\\My_App'],
binaries=None,
datas=added_files,
hiddenimports=[],
hookspath=[],
runtime_hooks=['rthook_pyqt4.py'],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher) …Run Code Online (Sandbox Code Playgroud) 我正在从*.ui文件加载QMainWIndow基础.此外,我有一个自定义小部件,我想放在窗体上的某个地方.目前我在.ui文件中放入一个空QVBoxLayout命名placeholder,并在QMainWindow子类中执行self.placeholder.addWidget(my_custom_widget)
在这种方法中我唯一不喜欢的是空布局没有自己的大小.我可以有一个布局一个细胞,并用虚拟控件(QLabel例如)与我想要的大小,更换这个小工具,然后添加我的自定义窗口小部件,但该方法似乎对我来说太多.
你完成这项任务的方法是什么?
我正在使用Python(PyQt4)
我试图在我的PySide GUI应用程序中做一个相当常见的事情:我想将一些CPU密集型任务委托给后台线程,以便我的GUI保持响应,甚至可以在计算进行时显示进度指示器.
这是我正在做的事情(我在Python 2.7,Linux x86_64上使用PySide 1.1.1):
import sys
import time
from PySide.QtGui import QMainWindow, QPushButton, QApplication, QWidget
from PySide.QtCore import QThread, QObject, Signal, Slot
class Worker(QObject):
done_signal = Signal()
def __init__(self, parent = None):
QObject.__init__(self, parent)
@Slot()
def do_stuff(self):
print "[thread %x] computation started" % self.thread().currentThreadId()
for i in range(30):
# time.sleep(0.2)
x = 1000000
y = 100**x
print "[thread %x] computation ended" % self.thread().currentThreadId()
self.done_signal.emit()
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
self.work_thread = QThread()
self.worker = Worker()
self.worker.moveToThread(self.work_thread) …Run Code Online (Sandbox Code Playgroud) 我想使用QString和QStringList中,但在PySide 1.1.0,他们不是模块,而不是在documents.so,我能做些什么用them.thank you.Not刚刚的QString和QStringList中,我找不到QTableModel ,QListModel等.
在Ubuntu中设置PySide进行开发的推荐方法是什么?
sudo apt-get install python3-pyside?sudo pip install pyside?sudo easy_install pyside?短版(tl; dr)
我正在学习PySide,大多数在线教程都super用来初始化UI元素.这是重要的(即,更具可扩展性),还是品味问题?
澄清:当我在详细版本中更清楚时,这不是另一个通知线程,询问何时使用super(这已经在之前完成).相反,考虑到使用PySide教程的数量super,而不是<class>.__init__,我想如果用弄清楚super是PySide应用程序的标准?如果是这样,是因为super在使用PySide/PyQt时需要特别提到的(涉及解决继承问题)?或者这是品味问题.
详细版本
我是Python的新手,目前正在使用Zets教程学习PySide(http://zetcode.com/gui/pysidetutorial/firstprograms/).本教程的第二个示例包括:
from PySide import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(300,300,250,150)
self.setWindowTitle("PySide 101: Window the First!")
self.show()
app=QtGui.QApplication(sys.argv)
ex=Example()
sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)
这工作正常,但我从未使用过super.因此,我重写了上面的代码,成功地替换super了父类的更标准的显式调用:
QtGui.QWidget.__init__(self)
Run Code Online (Sandbox Code Playgroud)
但是,当我在网上搜索PySide教程时(例如,http://qt-project.org/wiki/PySide-Newbie-Tutorials ),它们都包括调用super.我的问题是:我应该super用于PySide脚本吗?
看来,super当你有继承的钻石,它倾向于解决多重继承的情况下,以合理的方式似乎是最有帮助的.是否super与PySide一起使用,因为这些钻石的案例占优势,我会面对更现实的复杂例子?[编辑:否:请参阅下面的答案.]
我为什么要问?为什么不直接使用super并完成它?
我在问,因为我用来学习Python的书(学习Python,由Lutz撰写)花了20多页关于这个主题super,并明确告诫不要使用它.他建议新的Python用户在使用它之前采用更传统,更明确的路线(例如,参见第832页,学习Python的第1041-1064页,第5版).他基本上将它描绘成一种非剧性的,神秘的,很少需要的新风格,刚开始时你应该非常谨慎地对待它,并认为它被有经验的用户过度使用.
此外,查看两个主要的PySide/PyQt项目(Spyder和pyqtgraph)的源代码,两者都没有使用super.One(Spyder)明确告诉贡献者出于兼容性原因而避免使用它(http://code.google.com/p/spyderlib/wiki/NoteForContributors). …
pip install -U PySide根据官方网站说明运行时,有没有人知道如何避免以下错误:https://pypi.python.org/pypi/PySide/#installing-pyside-on-a-mac-os-x-system
请注意,我已经brew install qt成功完成了.
You are using pip version 7.0.3, however version 7.1.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Collecting PySide
Using cached PySide-1.2.4.tar.gz
Installing collected packages: PySide
Running setup.py install for PySide
Complete output from command /Applications/anaconda/bin/python -c "import setuptools, tokenize;__file__='/private/var/folders/dy/ttgqhqqx3g9bsbsnqnxsk2z80000gq/T/pip-build-CPxEmt/PySide/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /var/folders/dy/ttgqhqqx3g9bsbsnqnxsk2z80000gq/T/pip-0r7hrI-record/install-record.txt --single-version-externally-managed --compile:
Removing /private/var/folders/dy/ttgqhqqx3g9bsbsnqnxsk2z80000gq/T/pip-build-CPxEmt/PySide/pyside_package
running install
running build
Python architecture is 64bit
Inserting path …Run Code Online (Sandbox Code Playgroud)