Dockable window in Maya with PyQt - dialog

I use Maya 2016 + PyQt4.8
I create a simple window. It's worked. But i want dialog to be dockable.
import sip
import maya.OpenMayaUI as mui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import uic
import maya.cmds as cmds
#----------------------------------------------------------------------
def getMayaWindow():
ptr = mui.MQtUtil.mainWindow()
return sip.wrapinstance(long(ptr), QObject)
#----------------------------------------------------------------------
class SetTreeOnSplines(QDialog):
def __init__(self, parent=getMayaWindow()):
super(SetTreeOnSplines, self).__init__(parent)
uic.loadUi('X:/tools/Maya/windows/2016/python/setTree.ui', self)
#----------------------------------------------------------------------
# window
def setTree():
formCollect = SetTreeOnSplines()
formCollect.show()
#----------------------------------------------------------------------
# MAIN
setTree()
How to modify script using PyQt to the dialog was dockable?

import sip
import maya.OpenMayaUI as mui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import uic
import maya.cmds as cmds
windowTitle = "Set_Tree_On_Splines"
windowObject = "SetTreeOnSplinesWinObject"
#----------------------------------------------------------------------
def getMayaWindow():
ptr = mui.MQtUtil.mainWindow()
return sip.wrapinstance(long(ptr), QObject)
#----------------------------------------------------------------------
class SetTreeOnSplines(QDialog):
def __init__(self, parent=getMayaWindow()):
super(SetTreeOnSplines, self).__init__(parent)
uic.loadUi('X:/tools/Maya/windows/2016/python/setTree.ui', self)
self.setWindowTitle(windowTitle)
self.setObjectName(windowObject)
#----------------------------------------------------------------------
# window
def setTree():
if cmds.window(windowObject, q=True, exists=True):
print "Deleting ", windowObject
cmds.deleteUI(windowObject)
if cmds.dockControl( 'MayaWindow|'+windowTitle, q=True, ex=True):
print "Deleting ", 'MayaWindow|'+windowTitle
cmds.deleteUI( 'MayaWindow|'+windowTitle )
formCollect = SetTreeOnSplines()
cmds.dockControl( windowTitle, label=windowTitle.replace("_"," "), area='right', content=windowObject, allowedArea=['right', 'left'] )
#formCollect.show()
#----------------------------------------------------------------------
# MAIN
setTree()
I added two variables (windowTitle and windowObject), they are used to set the window title and the window object name once the UI is loaded.
I also added a check to see if the window and the dockable area already exist in order to delete them.

Related

QWidgetAction doesn't show up in QMenu in tray

Actually, my question is the same as this question but the answer didn't help too much, tried the same but didn't work.
I want to make a slider works in the tray but what I got is a blank field only.
Is it possible to accomplish this in PyQt5? I tried a lot of things but couldn't find a solution. If it is not possible in PyQt5 then which else library can I use for this?
My code:
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (
QSlider,
QHBoxLayout,
QLabel,
QApplication,
QWidgetAction,
)
from PyQt5.QtCore import Qt
def change_sound(value):
print(value)
class SliderWidgetAction(QFrame):
pass
class SliderAction(QWidgetAction):
def __init__(self, label="", parent=None):
QWidgetAction.__init__(self, parent)
self._widget = SliderWidgetAction(parent)
self._label = QLabel(label, self._widget)
self._slider = QSlider(Qt.Horizontal, self._widget)
self._slider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.value_changed = self._slider.valueChanged
def widget(self):
return self._widget
def label(self):
return self._label
def slider(self):
return self._slider
def createWidget(self, menu):
"""
This method is called by the QWidgetAction base class.
"""
actionWidget = self.widget()
actionLayout = QHBoxLayout(actionWidget)
actionLayout.setContentsMargins(0, 0, 0, 0)
actionLayout.addWidget(self.label())
actionLayout.addWidget(self.slider())
actionWidget.setLayout(actionLayout)
return actionWidget
app = QApplication([])
app.setQuitOnLastWindowClosed(False)
icon = QIcon("icon.png")
tray = QSystemTrayIcon()
tray.setIcon(icon)
tray.setVisible(True)
menu = QMenu()
action = SliderAction("Test", menu)
action.slider().setMinimum(10)
action.slider().setMaximum(100)
action.slider().setValue(90)
action.slider().valueChanged.connect(change_sound)
label_widget = QLabel("Hello World")
action.setDefaultWidget(label_widget)
menu.addAction(action)
tray.setContextMenu(menu)
app.exec_()

QObject: Cannot create children for a parent that is in a different thread. (Multithreading pyqt5)

I am trying to edit the text in 'QTextEdit' but I got the error which is in the title above. I know that I shouldn't edit the widgets in the main app from another thread and I searched for some answers, But I didn't get the full answer that I want
This is a sample that produce the same error that I have
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5 import QtCore
import sys
import time
import threading
class Main(QMainWindow):
def __init__(self):
super().__init__()
self.move(50, 220)
self.resize(500, 500)
self.text_edit = QTextEdit(self)
self.text_edit.resize(200, 200)
self.btn = QPushButton('start', self)
self.btn.move(10, 250)
self.btn.clicked.connect(lambda x : self.thread_creator(self.test))
self.btn2 = QPushButton('print', self)
self.btn2.move(10, 290)
self.btn2.clicked.connect(lambda x : print('dad'))
def test(self):
for i in range(99):
self.text_edit.setText(f'dad {i}')
time.sleep(0.1)
def thread_creator(self, function):
self.thread = threading.Thread(target=function)
self.thread.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Main()
ex.show()
sys.exit(app.exec_())

Can't call a message box in PyQt5 as a result of an if statement

I'm using Python 3 and PyQt5. I'm using QFileDialog.getOpenFileName to open different files into my program, but no more than 4, and I want to display a warning message box if you try to open another file, but can't seem to do it.
import pandas
import sys
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMainWindow, QAction, QFileDialog, QMessageBox
from PyQt5.QtCore import QSize
from PyQt5.QtGui import QIcon
class MainWindow(QMainWindow):
def __init__ (self):
QMainWindow.__init__(self)
self.setMinimumSize(QSize(640, 480))
self.setWindowTitle("'File' test")
self.count = 0
self.datasets = []
openFile = QAction(QIcon('open.png'), '&Open', self)
openFile.setShortcut('Ctrl+O')
openFile.setStatusTip('Open documents')
openFile.triggered.connect(self.openCall)
menuBar = self.menuBar()
fileMenu = menuBar.addMenu('&File')
fileMenu.addAction(openFile)
def openCall(self):
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
files, _ = QFileDialog.getOpenFileName(self, "Select one file to open", "C:\PROG\FIN", "CSV files (*.csv)", options=options)
if files:
if self.count < 4:
self.datasets.append(files)
self.count += 1
print(self.datasets)
print(self.count)
else:
# The message box should go here
Just add
QMessageBox.warning(self, "Title", "Description")

Screen functions in PYQT

import sys
from PyQt4 import QtCore, QtGui, uic
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import time
import datetime
import re
import random
import csv
from CropClass import *
from Wheat_class import *
from Potato_class import *
win1 = uic.loadUiType("MenuScreen.ui")[0]
win2 = uic.loadUiType("WheatScreen.ui")[0]
win3 = uic.loadUiType("PotatoScreen.ui") [0]
class MenuScreen(QtGui.QMainWindow, win1):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.setupUi(self)
self.BtnCreateSimulation.clicked.connect(self.changeSimulation)
def changeSimulation(self):
if self.RdoWheat.isChecked() ==True:
print("Wheat is picked")
new_crop=Wheat()
self.wheatSimulation()
elif self.RdoPotato.isChecked() == True:
print("Potato is picked")
new_crop = Potato()
self.PotatoSimulation()
def wheatSimulation(self):
print("Hello")
self.hide()
WheatWindow.show()
def PotatoSimulation(self):
self.hide()
PotatoWindow.show()
class PotatoScreen(QtGui.QMainWindow, win3):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.setupUi(self)
self.BtnBacktoMenu.clicked.connect(self.BackToMain)
def BackToMain(self):
self.hide()
MenuWindow.show()
class WheatScreen(QtGui.QMainWindow, win2):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.setupUi(self)
new_crop = Wheat()
self.BtnBacktoMenu.clicked.connect(self.BackToMain)
self.BtnManual.clicked.connect(self.ManualCalculate)
def BackToMain(self):
self.hide()
MenuWindow.show()
def ManualCalculate(self):
water = self.spBoxWater.value()
light= self.spBoxLight.value()
print("water", water, "light", light)
def main():
app = QtGui.QApplication(sys.argv)
WheatWindow = WheatScreen(None)
PotatoWindow = PotatoScreen(None)
MenuWindow = MenuScreen(None)
MenuWindow.show()
app.exec_()
if __name__ == "__main__":
main()
I have created a program in Python which simulates the growth rates of crops. The user is able to chose between the crop is wheat or potatoes I am trying to create a GUI using PYQT. The problem I am having is that when I try and load the program the program is not recognizing the other screen layouts. The main function should be setting up the screen layouts

Pyqt lunch separate Qtapplications in separate process

So what i would like to do is from the main Qt application start a bunch of separate Qt applications each on separate processes ... do their job then report to the main application when finished.
Could you guys point me in the right direction . I tried with multiprocessing but i get stuck initializing the separate Qt applications
Thank you
Something like this ... which is wrong
import sys
import multiprocessing
from multiprocessing import Pool
from PyQt4 import QtCore, QtGui ,QtNetwork
from PyQt4 import QtWebKit
from PyQt4.QtCore import *
from PyQt4.QtWebKit import *
from PyQt4.QtGui import QApplication
class SimpleWin(QtGui.QWidget):
def __init__(self, parent=None):
super(SimpleWin, self).__init__(parent)
self.buton = QtGui.QPushButton("START")
self.buton.clicked.connect(self.RunJob)
hbox = QtGui.QHBoxLayout()
hbox.addWidget(self.buton)
self.setLayout(hbox)
def RunJob(self):
print "RUUN"
jobs = []
for i in range(5):
p = multiprocessing.Process(target=Render,)
print i
jobs.append(p)
p.start()
class Render(QWebView,multiprocessing.Process):
def __init__(self, prox ):
self.app = QApplication(sys.argv)
QWebPage.__init__(self)
# self.crawl()
self.load(QUrl("http://www.ip-score.com/"))
self.show()
self.app.exec_()
def main():
app = QtGui.QApplication(sys.argv)
browse = SimpleWin()
browse.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Resources