I'm trying to create a small database app to keep all clients inside. I would like to write GUI using PyQt5. I have a problem with understanding how app structure should looks like.
I'd like to have a main class which starts the app and I want to seperate GUI, DB and Main classes in different files.
You can see my code snippets bellow. It don't work because some variables are not recognized and accually I don't understand why.
My thoughts:
1. Window, tab1 objects will be created in main class init function
2. When window, tab1 instances were created, the methods inside it's init will be called
3. I have window, tab1 objects and it's variables are available for themselves
window.gbT1Main.setLayout(T1LayMain) is not defined for TabNewClient class. Why ? How should I change my code to achieve above requirements? Please explain me how should I connect my classes :(
Window and TabNewClient class (window, tab1)
from PyQt5.QtWidgets import QApplication, QDialog, QTabWidget, QGroupBox, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QFormLayout, QLineEdit, QDateEdit, QTextEdit, QRadioButton, QGridLayout
import sys
import datetime
class Window(QDialog):
def __init__(self):
super().__init__()
self.InitWindow()
def InitWindow(self):
# create tab widget
self.tab = QTabWidget()
# create MainWindow groupbox
self.gbMainWindow = QGroupBox()
# TAB groupBoxes
self.gbT1Main = QGroupBox()
self.gbT2Main = QGroupBox("Main2")
self.gbT3Main = QGroupBox("Main3")
# Adding tabs
self.tab.addTab(self.gbT1Main, "Dodaj klienta")
self.tab.addTab(self.gbT2Main, "Wyszukaj")
self.tab.addTab(self.gbT3Main, "Statystki")
# Setting MainWindow title
self.setWindowTitle("MEDIKAP - gabinet medycyny pracy")
# Main Window Layout
self.layMainWindow = QHBoxLayout()
# Set MainWindow Layout
self.layMainWindow.addWidget(self.tab)
self.gbMainWindow.setLayout(self.layMainWindow)
# set MainWindow layout visible
self.setLayout(self.layMainWindow)
#show window
self.show()
class TabNewClient:
def __init__(self):
self.CreateTab1Layout()
def CreateTab1Layout(self):
self.gbAddClient = QGroupBox("Dane klienta")
self.gbRodzajBadania = QGroupBox("Podstawa prawna")
self.gbDane = QGroupBox()
self.gbComment = QGroupBox("Komentarz")
self.gbButtons = QGroupBox()
# TAB1 - layouts
T1LayMain = QVBoxLayout()
layDane = QHBoxLayout()
# TAB1
layDane.addWidget(self.gbAddClient)
layDane.addWidget(self.gbRodzajBadania)
self.gbDane.setLayout(layDane)
# TAB1 - set layout to Main
T1LayMain.addWidget(self.gbDane)
T1LayMain.addWidget(self.gbComment)
T1LayMain.addWidget(self.gbButtons)
window.gbT1Main.setLayout(T1LayMain)
Main class:
from PyQt5.QtWidgets import QApplication
import sys
from guiv3 import Window, TabNewClient
class Main:
def __init__(self):
window = Window()
tab1 = TabNewClient()
if __name__ == "__main__":
app = QApplication(sys.argv)
main = Main()
app.exec_()
error:
window.gbT1Main.setLayout(T1LayMain)
NameError: name 'window' is not defined
To answer the question of why you get an error about 'window' not being defined, I believe it's because there is no window variable in the TabNewClient class. It looks like you're attempting to refer to the window defined in Main, but that won't work since that variable isn't in the scope of the TabNewClient class. My guess is that you're going to run into the same issue with gbT1Main, since that is outside the scope of the TabNewClient class as well.
Edit: I think I understand what you're attempting here. You want the gbT1Main related tab in window to hold the layout from tab1. To do that, you will need to set window's layout in Main:
from PyQt5.QtWidgets import QApplication
import sys
from guiv3 import Window, TabNewClient
class Main:
def __init__(self):
window = Window()
tab1 = TabNewClient()
window.gbT1Main.setLayout(tab1.T1LayMain)
if __name__ == "__main__":
app = QApplication(sys.argv)
main = Main()
app.exec_()
That's most likely what you're looking for.
Important: this also requires that T1LayMain be an attribute of the TabNewClient class, so use self.T1LayMain inside that class for it to be accessible outside it.
Related
I am learning to write PyQt5 codes.When I tried to code a subclass extented from PyQt5.QWidget and to override its constructor function, I found that the new code didn't work.(A blank window without anything you coded would show up.)It seems that the program stopped after "super().init()".Even I think the constructor don't run.But when I put the lines except "super()._init()" in a overridden function "PyQt5.Qwidegt.show()", it runs well.I am wondering why.It is quite pluzzing for a green hand.
The codes are as followed:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout,
QPushButton
class VBoxLayoutWindow(QWidget):
def __int__(self):
super().__init__()
self.resize(300, 300)
self.setWindowTitle("VBox Layout")
layout = QVBoxLayout()
button1 = QPushButton("Button1")
button2 = QPushButton("Button2")
button3 = QPushButton("Button3")
layout.addWidget(button1)
layout.addWidget(button2)
layout.addWidget(button3)
layout.addStretch(2)
self.setLayout(layout)
app = QApplication(sys.argv)
w = VBoxLayoutWindow()
w.show()
app.exec_()
I'm currently doing a tutorial on how to create GUI apps from a book called "Modern PyQt" by Joshua Willman and I'm stuck right out of the gate:
I've copy pasted a basic code snippet from the book and tried to tweak it bit by bit instead of reading a bunch of text without any practical trial and error. I can display a window and adjust it's size and properties, but when I try to attach other widgets to the main window, they just don't show up.
Here's what I've got so far:
# First practical example from the book: Pomodoro time manager
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtGui import QIcon
class Pomodoro(QWidget):
def __init__(self): # Create default constructor
super().__init__()
self.initializeUI()
def initializeUI(self):
"""Initialize the window and display its contents to the screen."""
self.setGeometry(int((SCREEN_WIDTH-WINDOW_WIDTH)/2),int((SCREEN_HEIGHT-WINDOW_HEIGHT)/2),WINDOW_WIDTH,WINDOW_HEIGHT) # x,y,w,h
self.setWindowTitle('Bortism')
# self.setWindowIcon(QIcon("Borticon.png"))
self.button1 = QPushButton()
self.button1.setText('Button')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
WINDOW_WIDTH, WINDOW_HEIGHT = 1000,600
SCREEN_X, SCREEN_Y, SCREEN_WIDTH, SCREEN_HEIGHT = app.desktop().screenGeometry().getRect()
window = Pomodoro()
sys.exit(app.exec_())
For a widget to be shown as part of another then the requirement is that the first is the child of the second. This can be done by passing the parent or by using a layout (which is also passed to it by the parent). So in your case you must change to:
self.button1 = QPushButton(self)
I've created a QMenu in a widget outside of my main window, but when I try to show it on my Application it simply doesn't appear.
If I create the exact same QMenu in my main window class it appears without any issue.
from PyQt5.QtWidgets import (
QApplication,
QHBoxLayout,
QWidget,
QPushButton,
QMenu,
QAction
)
from PyQt5 import QtCore
class testWidget(QWidget):
def __init__(self):
menu = QMenu()
action = QAction("Test", checkable = True)
menu.addAction(action)
menu.addSeparator()
self.menu = menu
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Test pricer")
self.mainLayout = QHBoxLayout()
self.setLayout(self.mainLayout)
self.resize(900, 600)
self.button = QPushButton("Show menu")
self.button.clicked.connect(self.showMenu)
self.mainLayout.addWidget(self.button)
self.testWidget = testWidget()
def showMenu(self):
print(self.testWidget.menu.actions())
#self.testWidget.menu.setParent(self)
self.testWidget.menu.exec_(QtCore.QPoint(200, 200))
if __name__ == "__main__":
app = 0
app = QApplication([])
window = Window()
window.show()
app.exec_()
I tried changing the parent of the menu to the main window but that doesn't solve the problem either.
Would anyone know a way to show the menu while still creating it in another widget?
The QMenu is shown but not the item "Test" so the window is very small. "Test" is not displayed because QAction is removed since it is a local variable and no other variable takes ownership. There are 2 solutions:
Pass a parent to QAction: action = QAction("Test", checkable = True, parent=menu)
Make the QAction an attribute of the class by changing action to self.action.
I am new to Qt and PyQt and I appreciate it if someone can help me with this. I am trying to add a leaflet map to a GUI that I am creating using Qt designer and Python. Since there is no such widget, I create a simple Widget in the Qt Designer and promote it to a "LeafWidget" as shown below:
I save this file as (user_interface.ui) and then in my index.py file (under the same folder), I use the class leafWidget (with the same name as what defined in the Qt Designer) to define this new widget. I'm not sure if it is right or not. My "index.py" file that I run is as below.
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from pyqtlet import L, MapWidget
from PyQt5.uic import loadUiType
ui,_=loadUiType('user_interface.ui')
class LeafWidget (QWidget):
def __init__(self):
QWidget.__init__(self)
self.mapWidget = MapWidget()
self.map = L.map(self.mapWidget)
self.map.setView([39.764075, -86.159019], 10)
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(self.map)
self.layout = QVBoxLayout(self)
self.layout.addWidget(self.mapWidget)
self.show()
class MainApp(QMainWindow, ui):
def __init__(self):
QMainWindow.__init__(self)
self.setupUi(self)
self.mainWindow_tabWidget.setCurrentIndex(1)
def main():
app=QApplication(sys.argv)
window = MainApp()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
When I run it, it does open up the window, but the place for the map widget is empty as you see below. Am I defining this class correctly? In my MainApp class, do I need to add this new custom widget somehow? I don't get any specific errors in my debug console, So I'm not sure what I am missing.
I am trying to create a GUI for my python program. One of the tools that I need is a text input box.
Now, I want a text label for this box saying "Please insert texts." Is there a function to add a label that shows inside the input textbox as default and disappear when user click the box to type?
I don't mind to use qt designer or pyqt5 coding.
Thank you guys.
placeholderText : QString
This property holds the line edit's placeholder text
import sys
from PyQt5.QtWidgets import QLineEdit, QVBoxLayout, QApplication, QWidget
class Test(QWidget):
def __init__(self):
super().__init__()
self.lineEdit = QLineEdit(placeholderText="Please insert texts.") # <---
vbox = QVBoxLayout(self)
vbox.addWidget(self.lineEdit)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Test()
w.show()
sys.exit(app.exec_())
I am begginer like you and my English is not so good. But I recommend you use Qt Designer. It's easier, fastter for you draw your app. I am using pyside2 project and recommend you read docummentatio each widgets you wanna use in PySide2 project and Qt Project. Try code below
enter image description here
import sys
from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QDialog
from PySide2.QtWidgets import QTextEdit
from PySide2.QtWidgets import QVBoxLayout
from PySide2.QtCore import Qt
class MainDialog(QDialog):
def __init__(self, parent=None):
super(MainDialog, self).__init__(parent)
# Create Widget TextEdit
self.text = QTextEdit()
# I think that you wanna this function in your program
# https://doc.qt.io/qtforpython/PySide2/QtWidgets/QLineEdit.html?highlight=qlineedit#PySide2.QtWidgets.PySide2.QtWidgets.QLineEdit.setPlaceholderText
# http://doc.qt.io/qt-5/qlineedit.html#placeholderText-prop
self.text.setPlaceholderText('''Yes! this is exactly what I want!
Thank you, what if you have a big text box (more than 10 lines) and
you want to scale up the place holder and align it in center?? ''')
# https://doc.qt.io/qtforpython/PySide2/QtWidgets/QLineEdit.html?highlight=qlineedit#PySide2.QtWidgets.PySide2.QtWidgets.QLineEdit.setAlignment
# http://doc.qt.io/qt-5/qlineedit.html#alignment-prop
self.text.setAlignment(Qt.AlignCenter)
# Layout
layout = QVBoxLayout()
layout.addWidget(self.text)
self.setLayout(layout)
def main():
app = QApplication()
mainDialog = MainDialog()
mainDialog.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()