Встраивание стороннего приложения в python GUI
Необходимо в свой GUI встроить одним из виджетов окно xfce4 (не все настройки, а только некоторые, например xfce4-display-settings). Подскажите, какие есть рабочие способы это сделать на python-3.x ?
Пробовал в PyQt5 использовать createWindowContainer (window_id отлавливал через xwininfo), но оно не помещалось внутрь виджета, а открывалось поверх формы.
Опыты с gtk.Plug и gtk.Socket тоже не дали результата.
Ответы (2 шт):
Автор решения: S. Nick
→ Ссылка
я не совсем понял ваши пояснения, но отвечая на ваш прямой вопрос с использованием PyQt5,
это может выглядеть примерно так:
import sys
import subprocess
import threading
import time
import win32gui
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QWindow, QPixmap
from PyQt5.QtWidgets import (QWidget, QApplication, QVBoxLayout,
QGridLayout, QMainWindow, QLabel)
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.widget = QWidget()
self.widget.setFixedSize(230, 280)
self.widget.setStyleSheet("background-color: yellow;")
self.label = QLabel(self)
self.label.setPixmap(
QPixmap('images/splash_.jpg').scaled(self.size().width()/2, self.size().height())
)
self.grid_layout = QGridLayout(self.central_widget)
self.grid_layout.addWidget(self.widget, 0, 0, 2, 1)
self.v_layout = QVBoxLayout(self.widget)
self.initUI()
self.grid_layout.addWidget(self.label, 0, 1, 1, 1)
def initUI(self):
t = threading.Thread(target=self.runExe)
t.start()
hwnd1 = win32gui.FindWindowEx(0, 0, "CalcFrame", "Калькулятор")
start = time.time()
while hwnd1 == 0:
time.sleep(0.01)
hwnd1 = win32gui.FindWindowEx(0, 0, "CalcFrame", "Калькулятор")
end = time.time()
if end - start > 5:
return
window = QWindow.fromWinId(hwnd1)
widget = self.createWindowContainer(window, self.central_widget)
self.v_layout.addWidget(widget)
@staticmethod
def runExe():
exePath = "C:/Windows/system32/calc.exe"
subprocess.Popen(exePath)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.resize(550, 400)
ex.show()
sys.exit(app.exec_())
Автор решения: Artem Voyush
→ Ссылка
Нашел решение с использованием GTK+ 3.0
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk
from subprocess import Popen
class MainWindow(Gtk.ApplicationWindow):
def __init__(self):
Gtk.Window.__init__(self, title="Настройки")
self.set_border_width(10)
self.set_position(Gtk.WindowPosition.CENTER)
self.set_default_size(800, 480)
self.vbox = Gtk.Box(spacing=10, orientation='vertical')
self.add(self.vbox)
self.hbox1 = Gtk.Box(spacing=10, orientation='horizontal')
self.vbox.pack_start(self.hbox1, False, False, 0)
self.i_display = Gtk.Image()
self.i_display.set_from_file('image/display.png')
self.i_display.show()
self.b_display = Gtk.Button()
self.b_display.add(self.i_display)
self.b_display.show()
self.hbox1.pack_start(self.b_display, True, True, 0)
self.i_sesson = Gtk.Image()
self.i_sesson.set_from_file('image/setting.png')
self.i_sesson.show()
self.b_sesson = Gtk.Button()
self.b_sesson.add(self.i_sesson)
self.b_sesson.show()
self.hbox1.pack_start(self.b_sesson, True, True, 0)
widget = Gtk.Frame()
self.vbox.pack_start(widget, True, True, 0)
widget.hide()
self.b_display.connect("clicked", lambda x: self.Display_settings(widget))
self.b_sesson.connect("clicked", lambda x: self.Session_settings(widget))
self.label = Gtk.Label()
self.label.set_text("Для настройки необходимых параметров,\nиспользуйте кнопки.")
self.label.set_justify(Gtk.Justification.LEFT)
self.label.show()
self.vbox.pack_start(self.label, True, False, 0)
self.hbox2 = Gtk.Box(spacing=10, orientation='horizontal')
self.vbox.pack_start(self.hbox2, False, False, 0)
self.b_back = Gtk.Button(label='Назад')
self.b_back.set_property("width-request", 85)
self.b_back.set_property("height-request", 15)
self.b_back.show()
self.b_back.connect("clicked", lambda x: self.Back(widget))
self.hbox2.pack_start(self.b_back, True, True, 0)
self.b_exit = Gtk.Button(label='Выход')
self.b_exit.set_property("width-request", 85)
self.b_exit.set_property("height-request", 15)
self.b_exit.show()
self.b_exit.connect("clicked", Gtk.main_quit)
self.hbox2.pack_start(self.b_exit, True, True, 0)
self.vbox.show()
self.hbox1.show()
self.hbox2.show()
def Display_settings(self, widget):
widget.show()
self.label.hide()
self.hbox1.hide()
self.socket = Gtk.Socket()
widget.add(self.socket)
self.sock_id = str(self.socket.get_id())
self.socket.show()
cmd = ["xfce4-display-settings", "--socket-id=" + str(self.sock_id)]
Popen(cmd)
def Session_settings(self, widget):
widget.show()
self.label.hide()
self.hbox1.hide()
self.socket = Gtk.Socket()
widget.add(self.socket)
self.sock_id = str(self.socket.get_id())
self.socket.show()
cmd = ["xfce4-session-settings", "--socket-id=" + str(self.sock_id)]
Popen(cmd)
def Back(self, widget):
self.socket.destroy()
widget.hide()
self.hbox1.show()
self.label.show()
win = MainWindow()
win.connect("destroy", Gtk.main_quit)
win.show()
Gtk.main()
