Python PYQT Tabs outside app window [why] - python

Tabs added before app.exec_() is called look and act as any other tabs u met, though if adding another after the app.exec_() call makes the new tab 'detach' from the main app window. Pic below :)
Why? How can I make it move inside the window?
import threading
import time
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QFormLayout
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QTabWidget
from PyQt5.QtWidgets import QTextEdit
from PyQt5.QtWidgets import QWidget
class ATry(threading.Thread):
def __init__(self):
super().__init__()
def run(self):
time.sleep(1)
anotherTextEdit = QTextEdit()
anotherLineEdit = QLineEdit()
anotherLayout = QFormLayout()
anotherLayout.addRow(anotherTextEdit)
anotherLayout.addRow(anotherLineEdit)
anotherTab = QWidget()
anotherTab.setLayout(anotherLayout)
md.addTab(anotherTab, "Outside")
app = QApplication(sys.argv)
md = QTabWidget()
aTextEdit = QTextEdit()
aLineEdit = QLineEdit()
layout = QFormLayout()
layout.addRow(aTextEdit)
layout.addRow(aLineEdit)
thisTab = QWidget()
thisTab.setLayout(layout)
md.addTab(thisTab, "Inside")
a = ATry()
a.start()
md.show()
app.exec_()
Screen describing the problem

It works with QTimer or signals:
import sys
import time
from PyQt5.QtCore import QObject
from PyQt5.QtCore import QThread
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QFormLayout
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QTabWidget
from PyQt5.QtWidgets import QTextEdit
from PyQt5.QtWidgets import QWidget
class ATry(QThread):
def __init__(self, pointer):
super().__init__()
self.pointer = pointer
def run(self):
time.sleep(2)
self.pointer.emit()
def addTheTab():
anotherTextEdit = QTextEdit()
anotherLineEdit = QLineEdit()
anotherLayout = QFormLayout()
anotherLayout.addRow(anotherLineEdit)
anotherLayout.addRow(anotherTextEdit)
anotherTab = QWidget()
anotherTab.setLayout(anotherLayout)
md.addTab(anotherTab, "Whatever")
class MyQObject(QObject):
trigger = pyqtSignal()
def __init__(self):
super().__init__()
def connect_and_get_trigger(self):
self.trigger.connect(addTheTab)
return self.trigger
def getGFX(self):
app = QApplication(sys.argv)
md = QTabWidget()
md.show()
return app, md
obj = MyQObject()
app, md = obj.getGFX()
addTheTab()
a = ATry(obj.connect_and_get_trigger())
a.start()
# timer = QTimer()
# timer.timeout.connect(proba)
# timer.start(3000)
app.exec_()

Related

I'm trying to save the state of qtreeview with the directories expanded or not (load in the state I left when I closed .) using Qsettings but I can't

I am using the code below. Mainwindow's state is preserved but qtreeviw's is not.
import sys
from PyQt5.QtCore import QSettings, QByteArray
from PyQt5.QtWidgets import QApplication, QTreeView, QFileSystemModel, QVBoxLayout, QWidget
from PyQt5 import QtCore
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.tree = QTreeView()
self.settings = QSettings('testorg', 'testapp')
try:
self.tree.header().restoreState(self.settings.value("estado_header"))
self.resize(self.settings.value('window size'))
self.move(self.settings.value('window position'))
except:
pass
self.model = QFileSystemModel()
self.model.setRootPath(r"C:\Users\dan-s>")
self.tree.setModel(self.model)
#self.tree.header().restoreState(self.settings.value("estado_header"))
#self.tree.collapseAll()
layout = QVBoxLayout()
layout.addWidget(self.tree)
self.setLayout(layout)
def closeEvent(self, event):
self.settings.setValue('window size', self.size())
self.settings.setValue('window position', self.pos())
state = self.tree.header().saveState()
self.settings.setValue('estado_header', state)
super().closeEvent(event)
app = QApplication(sys.argv)
demo = MyApp()
demo.show()
sys.exit(app.exec_())
I've tried other ways but I can't solve it.

Problem integrating QFontComboBox in Qmenu

I'm trying to integrate QFontComboBox within Qmenu.
I try to make two things happen when selecting a particular font from the menu:
The Qmenu will close.
print the selected font.
from PyQt5.QtCore import QObject
from PyQt5.QtGui import QIcon, QFont, QCursor
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QFontComboBox, QWidgetAction, QMenu, QPushButton
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Pyside2 FontCombo Box")
self.setGeometry(300,200,300,250)
self.setFontBox()
self.setIcon()
self.show()
def setIcon(self):
appIcon = QIcon("icon.png")
self.setWindowIcon(appIcon)
def setFontBox(self):
self.font_button = QPushButton(self)
self.font_button.setFixedWidth(300)
self.font_button.clicked.connect(lambda: self.setFontmenu())
vbox = QVBoxLayout()
vbox.addWidget(self.font_button)
self.setLayout(vbox)
def setFontmenu(self):
font_menu = QMenu()
font_submenu = QFontComboBox()
font_submenu.setCurrentFont(QFont("Arial"))
objectTest = QObject()
widget = QWidgetAction(objectTest)
widget.setDefaultWidget(font_submenu)
font_menu.addAction(widget)
font_menu.exec_(QCursor.pos())
menu = font_menu
menu.addSeparator()
font_submenu.showPopup()
font_submenu.setFocus()
font_submenu.currentFontChanged.connect(self._changed)
def _changed(self):
font = self.currentFont().family()
print(font)
return
myapp = QApplication(sys.argv)
window = Window()
myapp.exec_()
sys.exit()

How to embed a cmd to pyqt5 application

I tried codes below, but it seemed not work as normal. I cannot use embedded cmd whatever I did. It looks like decorations. I mean I just want to use the cmd like the ordinary one. Here, I paste the code, and any advice would be greatly appreciated.
I develop this app on Python 3.7.3 conda environment, Window10.
import sys
import subprocess
import time
import win32gui
from PyQt5.QtCore import QProcess, Qt
from PyQt5.QtGui import QWindow, QIcon, QFont
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QMdiArea, QSplitter, QTextBrowser
from PyQt5.QtWidgets import QWidget, QApplication, QVBoxLayout
from win32com import client
from win32gui import GetWindowText, EnumWindows,SetForegroundWindow
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.p = QProcess()
self.layout = QVBoxLayout()
self.mdi = QMdiArea()
self.mainSplitter = QSplitter(Qt.Vertical)
self.setCentralWidget(self.mainSplitter)
self.mainSplitter.addWidget(QTextBrowser())
self.initUI()
def initUI(self):
self.runExe()
EnumWindows(self.set_cmd_to_foreground, None)
hwnd1 = win32gui.GetForegroundWindow()
#hwnd1 = win32gui.FindWindow(None, "C:\\Windows\\system32\\calc.exe")
print(hwnd1)
window = QWindow.fromWinId(hwnd1)
container_widge = self.createWindowContainer(window, self)
container_widge.setFocusPolicy(Qt.TabFocus)
container_widge.setFocus()
container_widge.setWindowTitle("ain")
container_widge.setFont(QFont("Times New Roman"))
container_widge.setGeometry(500, 500, 450, 400)
#container_widge.setFocusPolicy()
container_widge.activateWindow()
container_widge.acceptDrops()
container_widge.grabMouse()
container_widge.setMouseTracking(True)
self.mainSplitter.addWidget(container_widge)
self.showMaximized()
#self.setGeometry(200, 200, 700, 700)
#self.show()
def runExe(self):
shell.run("cmd.exe")
time.sleep(1)
def set_cmd_to_foreground(self, hwnd, extra):
"""sets first command prompt to forgeround"""
if "cmd.exe" in GetWindowText(hwnd):
print(hwnd)
SetForegroundWindow(hwnd)
return
def run_script(self, shell, scripts):
"""runs the py script"""
shell.SendKeys(scripts+"{ENTER}")
if __name__ == '__main__':
shell = client.Dispatch("WScript.Shell")
app = QApplication(sys.argv)
ex = Example()
#ex.run_script(shell, "python -m pip list")
#ex.show()
sys.exit(app.exec_())
you can try this I got it from this blog:
import sys
from PyQt5.QtCore import QProcess, QTextStream
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit,
QLineEdit, QVBoxLayout, QHBoxLayout, QWidget, QPushButton
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.process = QProcess(self)
self.output = QTextEdit(self)
self.input = QLineEdit(self)
self.run_command_button = QPushButton("Run Command", self)
layout = QVBoxLayout()
input_layout = QHBoxLayout()
input_layout.addWidget(self.input)
input_layout.addWidget(self.run_command_button)
layout.addLayout(input_layout)
layout.addWidget(self.output)
central_widget = QWidget(self)
central_widget.setLayout(layout)
self.setCentralWidget(central_widget)
self.process.readyReadStandardOutput.connect(self.read_output)
self.run_command_button.clicked.connect(self.run_command)
self.process.start("cmd.exe")
def read_output(self):
stream = QTextStream(self.process)
self.output.append(stream.readAll())
def run_command(self):
command = self.input.text() + "\n"
self.process.write(command.encode())
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

Not sure why textbox isn't showing

I'm making a simple browser with a search box in PyQt5. This is what I've written:
import PyQt5
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QAction, QLineEdit, QMessageBox, QMainWindow
from PyQt5.QtWebKitWidgets import QWebView , QWebPage
from PyQt5.QtWebKit import QWebSettings
from PyQt5.QtNetwork import *
import sys
from optparse import OptionParser
class App(QMainWindow):
def initiate(self):
super().initiate()
self.InitUI()
def initUI(self):
self.setWindowTitle('Browser')
self.setGeometry(100, 200, 1000, 2000)
self.searchbox = QLineEdit(self)
self.searchbox.move(20, 20)
self.searchbox.resize(1500,40)
self.go = QPushButton('Go', self)
self.go.move(1810, 20)
self.go.connect(self.gourl)
self.show()
def gourl(self):
url = self.searchbox.text()
class Browser(QWebView):
def __init__(self):
self.view = QWebView.__init__(self)
self.setWindowTitle('Loading...')
self.titleChanged.connect(self.adjustTitle)
def load(self,url):
self.setUrl(QUrl(url))
App.searchbox.setText(url)
def adjustTitle(self):
self.setWindowTitle(self.title())
app = QApplication(sys.argv)
view = Browser()
box = App()
box.show()
view.show()
view.load("https://duckduckgo.com")
app.exec_()
The browser part loads, but the textbox doesn't show. Python also throws this error:
Traceback (most recent call last):
File "C:\Users\Sid\Desktop\browser.py", line 43, in <module>
view.load("https://duckduckgo.com")
File "C:\Users\Sid\Desktop\browser.py", line 34, in load
App.searchbox.setText(url)
AttributeError: type object 'App' has no attribute 'searchbox'
I don't know why the textbox doesn't show, and I can't understand why the error is being thrown. Can someone please point out the error?
Thanks in advance. :)
What's New in Qt 5.6
https://doc.qt.io/qt-5/whatsnew56.html#removed-functionality
Porting from QtWebKit to QtWebEngine
https://doc.qt.io/qt-5/qtwebenginewidgets-qtwebkitportingguide.html
import sys
#import PyQt5
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QAction, QLineEdit, QMessageBox, QMainWindow
#from PyQt5.QtWebKitWidgets import QWebView , QWebPage
#from PyQt5.QtWebKit import QWebSettings
from PyQt5.QtWebEngine import *
from PyQt5.QtWebEngineWidgets import *
#from PyQt5.QtNetwork import *
#from optparse import OptionParser
class App(QMainWindow):
# def initiate(self):
# super().initiate()
def __init__(self, parent=None):
super().__init__(parent)
self.initUI() # - InitUI -> + initUI
def initUI(self):
self.setWindowTitle('Browser')
self.setGeometry(100, 200, 500, 400)
self.searchbox = QLineEdit("https://stackoverflow.com/questions/57841281/not-sure-why-textbox-isnt-showing", self)
self.searchbox.move(20, 20)
self.searchbox.resize(460,40)
self.go = QPushButton('Go', self)
self.go.move(370, 100)
self.go.clicked.connect(self.gourl) # clicked
self.show()
def gourl(self):
url = self.searchbox.text()
print(f"url = {url}")
self.webview = Browser()
self.webview.load(QUrl(url))
self.webview.show()
class Browser(QWebEngineView): #(QWebView):
windowList = []
def createWindow(self, QWebEnginePage_WebWindowType):
new_webview = Browser()
new_window = App()
new_window.setCentralWidget(new_webview)
#new_window.show()
self.windowList.append(new_window)
return new_webview
"""
def __init__(self, parent=None):
super().__init__(parent)
# self.view = QWebView.__init__(self)
self.setWindowTitle('Loading...')
self.titleChanged.connect(self.adjustTitle)
def load(self,url):
self.setUrl(QUrl(url))
App.searchbox.setText(url)
def adjustTitle(self):
self.setWindowTitle(self.title())
"""
if __name__ == "__main__":
app = QApplication(sys.argv)
# view = Browser()
box = App()
box.show()
# view.show()
# view.load("https://duckduckgo.com")
sys.exit(app.exec_())
Update
without a new window?? if possible
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QAction, QLineEdit,
QMessageBox, QMainWindow, QGridLayout)
from PyQt5.QtWebEngine import *
from PyQt5.QtWebEngineWidgets import *
class App(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.searchbox = QLineEdit("https://stackoverflow.com/questions/57841281/not-sure-why-textbox-isnt-showing", self)
self.go = QPushButton('Go', self)
self.go.clicked.connect(self.gourl)
self.webview = Browser()
self.grid = QGridLayout(centralWidget)
self.grid.addWidget(self.webview, 0, 0, 1, 2)
self.grid.addWidget(self.searchbox, 1, 0)
self.grid.addWidget(self.go, 1, 1)
def gourl(self):
url = self.searchbox.text()
self.webview.load(QUrl(url))
class Browser(QWebEngineView): #(QWebView):
windowList = []
def createWindow(self, QWebEnginePage_WebWindowType):
new_webview = Browser()
new_window = App()
new_window.setCentralWidget(new_webview)
#new_window.show()
self.windowList.append(new_window)
return new_webview
if __name__ == "__main__":
app = QApplication(sys.argv)
box = App()
box.setWindowTitle('Browser')
box.resize(600, 500)
box.show()
sys.exit(app.exec_())

first argument of unbound method must have type 'QWidget' [duplicate]

This question already has an answer here:
How to fix error in my pyqt programm (first argument of unbound method must have type 'QDialog') ?
(1 answer)
Closed 3 years ago.
I'm trying to build a GUI app using PyQt5 and Python 3.7 and I've decided to break the code in different modules. When i try to import a function that creates an instance of a custom widget, an error related to 'sis'. What I read is that 'sis' is a way of encapsulation C/C++ code to be run in python. But how can I work with that?
This is the code that runs the app:
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setGeometry(10,35,1500,800)
self.setWindowTitle("Cotizador TuCheff")
#self.setWindowIcon(QtGui.QIcon(''))
mainWindow(self)
def mainWindow(self):
from PyQt5 import QtCore, QtGui, QtWidgets
from Pages.Quote import quote
barMenu = QtWidgets.QTabWidget(self)
tab1 = QtWidgets.QWidget()
quoteLayout = QtWidgets.QVBoxLayout()
quoteGenerator = quote.makeQuoteWindow()
quoteLayout.addWidget(quoteGenerator)
tab1.setLayout(quoteLayout)
barMenu.addTab(tab1, "&Nueva CotizaciĆ³n")
self.setCentralWidget(barMenu)
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
And file, where I try to get a custom widget, is:
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication
import sys
def makeQuoteWindow():
quoteWindow = QuoteWindow
quoteWindow.create()
#app = QApplication([])
#window = quoteWindow()
#window.show()
#status = app.exec_()
#sys.exit(status)
class QuoteWindow(QtWidgets.QWidget):
def __init__(self):
super(QuoteWindow, self).__init__()
def create(self):
mainWidget = QtWidgets.QWidget()
vLayout1 = QtWidgets.QVBoxLayout()
#=======------------------------ UPPER SIDE -------------------
hLayout1 = QtWidgets.QHBoxLayout()
##A LOT OF WIDGETS AND LAYOUTS
hLayout2 = QtWidgets.QHBoxLayout()
#display content
vLayout1.addLayout(hLayout1)
vLayout1.addLayout(hLayout2)
hLayout2.addItem(vSpacer1)
mainWidget.setLayout(vLayout1)
return mainWidget
if __name__ == "__main__":
makeQuoteWindow()
The error is:
TypeError: create(self, window: sip.voidptr = 0, initializeWindow: bool = True, destroyOldWindow: bool = True): first argument of unbound method must have type 'QWidget'
Try it:
main.py
import sys
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWidgets import QApplication, QMainWindow
# from Pages.Quote import quote
from Quote import QuoteWindow
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setGeometry(10,35,1500,800)
self.setWindowTitle("Cotizador TuCheff")
self.setWindowIcon(QtGui.QIcon('im.png'))
# mainWindow(self)
self.mainWindow()
def mainWindow(self):
# from Pages.Quote import quote
self.quoteWindow = QuoteWindow() # +++
barMenu = QtWidgets.QTabWidget(self)
tab1 = QtWidgets.QWidget()
quoteLayout = QtWidgets.QVBoxLayout()
# quoteGenerator = quote.makeQuoteWindow()
# quoteLayout.addWidget(quoteGenerator)
quoteLayout.addWidget(self.quoteWindow) # +++
tab1.setLayout(quoteLayout)
barMenu.addTab(tab1, "&Nueva CotizaciĆ³n")
self.setCentralWidget(barMenu)
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
Quote.py
from PyQt5 import QtCore, QtWidgets, QtGui
class QuoteWindow(QtWidgets.QWidget):
def __init__(self):
super(QuoteWindow, self).__init__()
def create(self):
mainWidget = QtWidgets.QWidget()
vLayout1 = QtWidgets.QVBoxLayout()
#=======------------------------ UPPER SIDE -------------------
hLayout1 = QtWidgets.QHBoxLayout()
##A LOT OF WIDGETS AND LAYOUTS
hLayout2 = QtWidgets.QHBoxLayout()
#display content
vLayout1.addLayout(hLayout1)
vLayout1.addLayout(hLayout2)
hLayout2.addItem(vSpacer1)
mainWidget.setLayout(vLayout1)
return mainWidget

Categories

Resources