PYQt5 i kolejne okno

PYQt5 i kolejne okno
RG
  • Rejestracja:około 5 lat
  • Ostatnio:około 13 godzin
  • Lokalizacja:Sardine, Italy
  • Postów:187
0

Witam ponownie.

Czytam i czytam posty i głowa mnie boli.

Próbuję rozgryźć jak w temacie. Wymęczyłem coś takiego. Działa, ale pojawia się jeden dziwny i oczywisty błąd:

Kopiuj

import sys
from PyQt5.QtWidgets import *

def f_btn_new():
	print('tutaj')

def f_btn_www():
	okno_new=QWidget()
	okno_new.setGeometry(450, 250, 200, 100)
	btn_2=QPushButton('Guzik', parent=okno_new)
	btn_2.clicked.connect(f_btn_new)
	btn_2.move(20,20)
	okno_new.show()
	okno_new() # TUTAJ jest błąd
	return

prog = QApplication(['Radek'])
okno=QWidget()
okno.setGeometry(100, 200, 500, 190)
btn_1=QPushButton('Nowe okno', parent=okno)
btn_1.clicked.connect(f_btn_www)
btn_1.move(20,20)
okno.show()
sys.exit(prog.exec_())

Błąd:
okno_new()
TypeError: 'QWidget' object is not callable
Ale bez tej linii nie działa, a z nią jest ok.

Co wywołać zamiast niej, aby funkcjonalne było drugie okno. AAA teraz jest. Próbowałem .exec lub exec_ bo gdzieś znalazłem.
Jakieś rady.

I jeszcze proszę o wyjaśninie. QWidget i QWindow. Tu na forum był post i wyjasnienie, że QWidget jest gdy chcemy jakieś własne cuda robić, a powinno się używać QWindow. Próbuję, ale nawet nie jestem wstanie QLabel nanieść. Robię:

Kopiuj
okno=QWindow()
okno.setGeometry(100,100,300,100)
tekst=QLabel('Tekst') # , parent=okno) # Ma być, chyba nie
tekst.move(20,20)

Cała reszta jest jak show()
I otwiera się, ale takie niewypełnione, jak "zawieszone", z grafiką ze wszystkim spod. Dziwne.

Pozdrawiam
Głębicki

RG
O QWindow już coś wyczytałem. Za: https://doc.qt.io/qtforpython/PySide2/QtGui/QWindow.html#more "An application will typically use QWidget or QQuickView for its UI, and not QWindow directly. Still, it is possible to render directly to a QWindow with QBackingStore or QOpenGLContext , ..." więc proszę tylko o początek.
RG
Znalazłem rozwiązanie w postaci zastosowania dla drugiego okna QDialog w miejsce QWidget i wywołania drugiego okna za pomocą .exec_(). Główne okno jest też całkowicie nieaktywne więc nie da się go zamknąć. A dla zainteresowanych rozwiązaniem mojego pierwszego problemu dwóch okien było "przygotowanie okna" i w funkcji button pokazanie tylko tego drugiego okna .show() . Były daw okna, ale problemem była możliwość zamknięcia pierwszego/głównego. QDialog rozwiązuje ten problem.
RG
  • Rejestracja:około 5 lat
  • Ostatnio:około 13 godzin
  • Lokalizacja:Sardine, Italy
  • Postów:187
0
  1. O QWindow już coś wyczytałem. Za: https://doc.qt.io/qtforpython/PySide2/QtGui/QWindow.html#more "An application will typically use QWidget or QQuickView for its UI, and not QWindow directly. Still, it is possible to render directly to a QWindow with QBackingStore or QOpenGLContext , ..." więc proszę tylko o początek.

  2. Znalazłem rozwiązanie w postaci zastosowania dla drugiego okna QDialog w miejsce QWidget i wywołania drugiego okna za pomocą .exec_(). Główne okno jest też całkowicie nieaktywne więc nie da się go zamknąć. A dla zainteresowanych rozwiązaniem mojego pierwszego problemu dwóch okien było "przygotowanie okna" i w funkcji button pokazanie tylko tego drugiego okna .show() . Były daw okna, ale problemem była możliwość zamknięcia pierwszego/głównego. QDialog rozwiązuje ten problem. -

RG
  • Rejestracja:około 5 lat
  • Ostatnio:około 13 godzin
  • Lokalizacja:Sardine, Italy
  • Postów:187
0

Może kogoś zainteresuje. Docelowy efekt to po kliknięciu guziczka w głównym oknie następuje otwarcie drugiego okna z podglądem lokalnej strony www.

Kopiuj
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

from PyQt5.QtWebKitWidgets import QWebPage
from PyQt5.QtWebKitWidgets import QWebView

def f_btn_www():
	okno_new=QDialog()
	okno_new.setGeometry(450, 250, 950, 500)
	okno_new.setWindowTitle("Okno dla strony WWW")
	www1=QWebView(okno_new)
	www1.setGeometry(0,0,950,500)
	local_url = QUrl.fromLocalFile("/home/radek/Pulpit/test.html")
	www1.load(local_url)
	okno_new.exec_()
	return

prog = QApplication([' '])
okno=QWidget()
okno.setGeometry(100, 200, 500, 190)
okno.setWindowTitle('Okno główne')
btn_1=QPushButton('Nowe okno', parent=okno)
btn_1.clicked.connect(f_btn_www)
btn_1.move(20,20)
okno.show()

sys.exit(prog.exec_())
```

Pozdrawiam forumowiczów
Radek
AL
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 3 lata
  • Postów:1493
0

IMHO źle. Po cholerę odpalać nową petlę zdarzeń?
Abstrahując już już od polskich nazw...

Kopiuj
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

def www_window():
    okno_new=QDialog() #QWidget...co tam chcesz w sumie
    okno_new.setGeometry(450, 250, 950, 500)
    okno_new.setWindowTitle("Okno dla strony WWW")
#whatever... nie mam QWebToolkit u siebie
    return okno_new

prog = QApplication([' '])
www = www_window()
okno=QWidget()
okno.setGeometry(100, 200, 500, 190)
okno.setWindowTitle('Okno glowne')
btn_1=QPushButton('Nowe okno', parent=okno)
btn_1.clicked.connect(www.show)
btn_1.move(20,20)
okno.show()

sys.exit(prog.exec_())
edytowany 1x, ostatnio: alagner
RG
hej. dzieki. Pytanie. Jak się ma QWidget, a QDialog do zablokowania/nieaktywności głównego okna. Bo w Twoim przykładzie główne okno można zamknąć. Trzeba bawić się z Modality itd. QDialog rozwiązuje problem. I przepraszam, że użyłem okno. Już wszędzie zmieniam.
semicolon
Wygląda na to, że druga pętla wykonywała się w ramach tego samego wątku i odcinała zdarzenia związane z głównym oknem. Gdy użyłeś tylko show to oba okna mogą przyjmować zdarzenia więc użytkownik może bez problemu zamknąć główne okno. Najlepszym wyjściem wg dokumentacji byłoby uzycie akcji open, która to lepiej obsługuje, rzuć okiem na sekcję note: https://doc.qt.io/qt-5/qdialog.html#exec
RG
Ale do kogo ty piszesz? Ja już rozwiązałem swój problem. Używam QDialog, który automatycznie blokuje pierwsze okno. Rozwiazanie podane przez alagner nie jest rozwiązaniem. A jego rozwiązanie miałem wcześniej. Może nie identyczne. Ludzie nie czytają. Ach. Nieważne. QDialog działa.
semicolon
Do Ciebie - ale najwyraźniej masz to w poważaniu.
RG
Przecież to nie rozwiązuje problemu. W przykładzie alagner zmiana na .open dalej pozwala zamknąć pierwsze okno. W moim przykładzie to QWidget nie ma metody .open. Nie rozumiem. Jak to ma pomóc?
AL
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 3 lata
  • Postów:1493
0

Primo: nie odpowiadajcie w komentarzach
@Radosław Głębicki: błędem jest odpalanie nowej pętli zdarzeń w tym samym wątku, od tego jest jego właściwość modality. Wg dokumentacji open powinien otworzyć okienko w ten sposób. O dziwo to tak nie działa. Ok, ale zawsze można ręcznie:
Zobacz tak:

Kopiuj
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

def www_window():
    okno_new=QDialog() #QWidget...co tam chcesz w sumie
    okno_new.setModal(True)
    okno_new.setGeometry(450, 250, 950, 500)
    okno_new.setWindowTitle("Okno dla strony WWW")
#whatever... nie mam QWebToolkit u siebie
    return okno_new

prog = QApplication([' '])
www = www_window()
okno=QWidget()
okno.setGeometry(100, 200, 500, 190)
okno.setWindowTitle('Okno glowne')
btn_1=QPushButton('Nowe okno', parent=okno)
btn_1.clicked.connect(www.show)
btn_1.move(20,20)
okno.show()

sys.exit(prog.exec_())

EDIT: a tak btw, dla tego dialogu ustawiłbym parenta na okno... no ale to niejako osobny temat.

edytowany 2x, ostatnio: alagner
RG
Ustawiłem parent na okno wyższe. Dzięki. Działa z setModal. Dzięki.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.